关于jquery delegate的疑惑

一天要饭生活又开始啦 2013-09-11 01:03:13
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type='text/css'>
dl dt { width:100px; float:left; }
dl dd { margin-left:200px; }
</style>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript'>
var clone;
$(function() {
$('dl dd').click(function() {
$(this).html("<input type='text' /> <select><option value='Work'>Work</option></select> <span class='close'>x</span><br /><span class='another'>Add another</span>");
clone = $(this).clone(true);
});
/*$('.close').live('click', function() {
$(this).parent().html('Add a phone number');
});*/
$('dl dd').delegate('.close', 'click', function(e) {
//$(this).parent().html('Add a phone number');
e.stopPropagation();
$(this).parent().html('Add a phone number');
});
/*$('dl dd input').keydown(function() {
$('this').parent().append("<br /><span class='another'>Add another</span>");
});*/
$('dl dd').delegate('input', 'click', function(e) {
e.stopPropagation();
});
/*$('.another').live('click', function() {
$(this).parent().parent().append(clone);
});*/
$('dl').delegate('.another', 'click', function(e) {
e.stopPropagation();
$(this).parent().parent().append(clone);
});

});
</script>
</head>

<body>
<dl>
<dt>Phone</dt>
<dd class='dd'>Add a phone number</dd>
</dl>
</body>
</html>

点击another为什么不添加
...全文
318 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 21 楼 qwklove 的回复:
[quote=引用 20 楼 veryhunger 的回复:] [quote=引用 19 楼 qwklove 的回复:] 不知道楼主有没有已经把冒泡问题解决掉~ 其实,楼主这段代码: 1.最开始由于delegate的机制存在冒泡问题,所以无法添加新dd; 2.把冒泡修改好后,楼主可能会发现:还是无法添加新dd; 不知道楼主现在是1,2中哪个情况: 如果是1,那么首先要把冒泡问题解决掉,比如把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...)。 如果是2,那么问题就在于clone()这个方法。 ps:虽在本帖回复,但测试仍然用的是原帖楼主的代码。
属于情况二,你说的把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...) 我感觉不理解 $('dl').delegate('.another'...)是给dl下的所有.another添加代理事件句柄,包括后来添加的 可是改成$('dl dd').delegate('.another'...), 由于开始页面只有一个dd标签,也就只给第一个dd下的.another添加了代理事件句柄 后来添加的dd下的.another应该添加不到吧?[/quote] (1)用delegate进行绑定,不管元素是已经存在在页面上的还是后来动态添加的,都会被绑定。 这也正是delegate绑定和bind绑定的区别之处,delegate自jquery-1.7以上就已经被on代替了,on与delegate是同效的。 (2)拿你的代码来讲,增加一个新dd后,再点击新dd中的another无效和delegate是无关的,问题在于clone这个方法。你可以把clone=$(this).clone(true);换成clone='<p>content</p>',即把clone赋值为html字符串,然后再点击another,和之前的代码运行情况对比一下。 (3)至于clone这个方法的什么特性引发的another无效,楼主可以自行google一下,单独测测clone这个方法。[/quote]
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript'>
/*$(function() {
	$('dl').delegate('.another', 'click', function() {
		alert('dd');
	});
	$('button').click(function() {
		$('dl').append($("<dd><div class='another'>gggggggggggggg</div></dd>"));
	});
});*/
$(function() {
	$('dl dd').delegate('.another', 'click', function() {
		alert('dd');
	});
	$('button').click(function() {
		$('dl').append($("<dd><div class='another'>gggggggggggggg</div></dd>"));
	});
});
</script>
</head>

<body>
<dl>
	<dd>
		<div class='another'>sfsfsf</div>
	</dd>
</dl>
<button>按钮</button>
</body>
</html>
我的疑惑是给dd click如果不用代理就只能给一个dd加 click 如果用代理 即$('dl')给所有dl下的dd加click,那么后来添加的.another也被添加了事件了 我这个例子证明了这个问题 如果用$('dl dd')的话,那么通过button添加的.another就得不到代理事件了
  • 打赏
  • 举报
回复
引用 27 楼 qwklove 的回复:
[quote=引用 26 楼 veryhunger 的回复:] [quote=引用 23 楼 qwklove 的回复:] [quote=引用 22 楼 veryhunger 的回复:] [quote=引用 21 楼 qwklove 的回复:] [quote=引用 20 楼 veryhunger 的回复:] [quote=引用 19 楼 qwklove 的回复:] 不知道楼主有没有已经把冒泡问题解决掉~ 其实,楼主这段代码: 1.最开始由于delegate的机制存在冒泡问题,所以无法添加新dd; 2.把冒泡修改好后,楼主可能会发现:还是无法添加新dd; 不知道楼主现在是1,2中哪个情况: 如果是1,那么首先要把冒泡问题解决掉,比如把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...)。 如果是2,那么问题就在于clone()这个方法。 ps:虽在本帖回复,但测试仍然用的是原帖楼主的代码。
属于情况二,你说的把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...) 我感觉不理解 $('dl').delegate('.another'...)是给dl下的所有.another添加代理事件句柄,包括后来添加的 可是改成$('dl dd').delegate('.another'...), 由于开始页面只有一个dd标签,也就只给第一个dd下的.another添加了代理事件句柄 后来添加的dd下的.another应该添加不到吧?[/quote] (1)用delegate进行绑定,不管元素是已经存在在页面上的还是后来动态添加的,都会被绑定。 这也正是delegate绑定和bind绑定的区别之处,delegate自jquery-1.7以上就已经被on代替了,on与delegate是同效的。 (2)拿你的代码来讲,增加一个新dd后,再点击新dd中的another无效和delegate是无关的,问题在于clone这个方法。你可以把clone=$(this).clone(true);换成clone='<p>content</p>',即把clone赋值为html字符串,然后再点击another,和之前的代码运行情况对比一下。 (3)至于clone这个方法的什么特性引发的another无效,楼主可以自行google一下,单独测测clone这个方法。[/quote]
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript'>
/*$(function() {
	$('dl').delegate('.another', 'click', function() {
		alert('dd');
	});
	$('button').click(function() {
		$('dl').append($("<dd><div class='another'>gggggggggggggg</div></dd>"));
	});
});*/
$(function() {
	$('dl dd').delegate('.another', 'click', function() {
		alert('dd');
	});
	$('button').click(function() {
		$('dl').append($("<dd><div class='another'>gggggggggggggg</div></dd>"));
	});
});
</script>
</head>

<body>
<dl>
	<dd>
		<div class='another'>sfsfsf</div>
	</dd>
</dl>
<button>按钮</button>
</body>
</html>
我的疑惑是给dd click如果不用代理就只能给一个dd加 click 如果用代理 即$('dl')给所有dl下的dd加click,那么后来添加的.another也被添加了事件了 我这个例子证明了这个问题 如果用$('dl dd')的话,那么通过button添加的.another就得不到代理事件了[/quote] (1)你已经基本得出结论了~ 还是delegate的问题:

$('选择器A').delegate('选择器B','eventType',function(){...});
选择器A只针对页面上已存在的元素,也就是说delegate只对执行时页面上已存在的元素进行绑定,不负责执行后又动态添加的元素。 (2)用你的代码来说,就是:

$('dl dd').delegate('.another', 'click', function() {
        alert('dd');
    });
这一句在执行的时候,‘.another’在页面上存在与否不重要,但是‘dl dd’必须是存在的(如果不存在匹配‘dl dd’的元素,那么这个delegate的绑定就相当于给不存在的元素进行绑定--无效且毫无意义;如果存在,则对每个匹配的元素进行绑定)。 而你的代码这一句在执行的时候,html中只有一个dd,所以只给这个dd进行了绑定。至于后面新添加的dd,因为这些dd在delegate执行的时候是不存在的,所以不会被绑定事件函数。 改成$('dl')为什么都会弹出,相信楼主也已经明白了吧~[/quote] 还有个地方不明白
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript'>
$(function() {
	$('#divId').click(function() {
		alert('click');
		//$('#di').attr('id', 'divd');
		$(this).html("<div class='di'>sfsfsfsfsfsfsfsf</div>");
	});
	$(document).delegate('.di', 'click', function() {
		alert('delegate');
	});
});
</script>
</head>

<body>
<div id='divId'>
	<div class='di'>
		ljljljsfsfsf
	</div>
</div>
</body>
</html>
为什么这样可以
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type='text/css'>
dl dt { width:100px; float:left; }
dl dd { margin-left:200px; }
</style>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>  
<script type='text/javascript'>
var clone;
$(function() {
  $('dl dd').click(function() {
    //$(this).html("<input type='text' /> <select><option value='Work'>Work</option></select> <span class='close'>x</span><br /><span class='another'>Add another</span>");
    $(this).html("<span class='another'>Add another</span>");
	clone = $(this).clone(true);
	alert('click');
  });
  $('dl').delegate('.another', 'click', function() {
    //e.stopPropagation();
	alert('another');
    $(this).parent().parent().append(clone);
  });
   
});
</script>
</head>
    
<body>
<dl>
  <dt>Phone</dt>
  <dd class='dd'>Add a phone number<span class='another'>sfsfsfsfsf</span></dd>
</dl>
</body>
</html>
这样不行呢?[/quote] 在不行的这段代码中,实际执行如下: 点击another,click事件开始冒泡==>another并没有绑定click事件函数所以冒泡到dd==>因为dd被绑定了click事件函数,所以dd的click函数开始执行(执行内容为将当前dd内的html替换成新的html->'<span class='another'>Add another</span>',然后把dd节点复制给变量clone,最后弹出字符串“click”)==>dd的监听函数执行完后,click继续冒泡到dl==>dl上虽然绑定了click函数,但是是通过delegate绑定的,所以需要先检查你最开始点击的那个元素是否匹配选择器‘.another’,但是:此时你点击的那个another早已不存在了,因为dd的监听函数执行时已经重写了dd内的html(你可以理解为删除了原来的another然后又新添加了一个another),即使新写的another和你点击的那个another是一模一样的,他们两个也是毫无关系彼此独立的。之前讲过‘匹配’这个条件必需满足才会触发事件函数,现在既然元素已经不存在,delegate关于是否匹配的的检查也就无法进行,最终dl上的函数也就无法被触发,即无法弹出another。 唉 讲的我口干舌燥~~~求结贴~ [/quote] 好吧,感谢大家了
阿鱼 2013-09-13
  • 打赏
  • 举报
回复
引用 26 楼 veryhunger 的回复:
[quote=引用 23 楼 qwklove 的回复:] [quote=引用 22 楼 veryhunger 的回复:] [quote=引用 21 楼 qwklove 的回复:] [quote=引用 20 楼 veryhunger 的回复:] [quote=引用 19 楼 qwklove 的回复:] 不知道楼主有没有已经把冒泡问题解决掉~ 其实,楼主这段代码: 1.最开始由于delegate的机制存在冒泡问题,所以无法添加新dd; 2.把冒泡修改好后,楼主可能会发现:还是无法添加新dd; 不知道楼主现在是1,2中哪个情况: 如果是1,那么首先要把冒泡问题解决掉,比如把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...)。 如果是2,那么问题就在于clone()这个方法。 ps:虽在本帖回复,但测试仍然用的是原帖楼主的代码。
属于情况二,你说的把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...) 我感觉不理解 $('dl').delegate('.another'...)是给dl下的所有.another添加代理事件句柄,包括后来添加的 可是改成$('dl dd').delegate('.another'...), 由于开始页面只有一个dd标签,也就只给第一个dd下的.another添加了代理事件句柄 后来添加的dd下的.another应该添加不到吧?[/quote] (1)用delegate进行绑定,不管元素是已经存在在页面上的还是后来动态添加的,都会被绑定。 这也正是delegate绑定和bind绑定的区别之处,delegate自jquery-1.7以上就已经被on代替了,on与delegate是同效的。 (2)拿你的代码来讲,增加一个新dd后,再点击新dd中的another无效和delegate是无关的,问题在于clone这个方法。你可以把clone=$(this).clone(true);换成clone='<p>content</p>',即把clone赋值为html字符串,然后再点击another,和之前的代码运行情况对比一下。 (3)至于clone这个方法的什么特性引发的another无效,楼主可以自行google一下,单独测测clone这个方法。[/quote]
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript'>
/*$(function() {
	$('dl').delegate('.another', 'click', function() {
		alert('dd');
	});
	$('button').click(function() {
		$('dl').append($("<dd><div class='another'>gggggggggggggg</div></dd>"));
	});
});*/
$(function() {
	$('dl dd').delegate('.another', 'click', function() {
		alert('dd');
	});
	$('button').click(function() {
		$('dl').append($("<dd><div class='another'>gggggggggggggg</div></dd>"));
	});
});
</script>
</head>

<body>
<dl>
	<dd>
		<div class='another'>sfsfsf</div>
	</dd>
</dl>
<button>按钮</button>
</body>
</html>
我的疑惑是给dd click如果不用代理就只能给一个dd加 click 如果用代理 即$('dl')给所有dl下的dd加click,那么后来添加的.another也被添加了事件了 我这个例子证明了这个问题 如果用$('dl dd')的话,那么通过button添加的.another就得不到代理事件了[/quote] (1)你已经基本得出结论了~ 还是delegate的问题:

$('选择器A').delegate('选择器B','eventType',function(){...});
选择器A只针对页面上已存在的元素,也就是说delegate只对执行时页面上已存在的元素进行绑定,不负责执行后又动态添加的元素。 (2)用你的代码来说,就是:

$('dl dd').delegate('.another', 'click', function() {
        alert('dd');
    });
这一句在执行的时候,‘.another’在页面上存在与否不重要,但是‘dl dd’必须是存在的(如果不存在匹配‘dl dd’的元素,那么这个delegate的绑定就相当于给不存在的元素进行绑定--无效且毫无意义;如果存在,则对每个匹配的元素进行绑定)。 而你的代码这一句在执行的时候,html中只有一个dd,所以只给这个dd进行了绑定。至于后面新添加的dd,因为这些dd在delegate执行的时候是不存在的,所以不会被绑定事件函数。 改成$('dl')为什么都会弹出,相信楼主也已经明白了吧~[/quote] 还有个地方不明白
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript'>
$(function() {
	$('#divId').click(function() {
		alert('click');
		//$('#di').attr('id', 'divd');
		$(this).html("<div class='di'>sfsfsfsfsfsfsfsf</div>");
	});
	$(document).delegate('.di', 'click', function() {
		alert('delegate');
	});
});
</script>
</head>

<body>
<div id='divId'>
	<div class='di'>
		ljljljsfsfsf
	</div>
</div>
</body>
</html>
为什么这样可以
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type='text/css'>
dl dt { width:100px; float:left; }
dl dd { margin-left:200px; }
</style>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>  
<script type='text/javascript'>
var clone;
$(function() {
  $('dl dd').click(function() {
    //$(this).html("<input type='text' /> <select><option value='Work'>Work</option></select> <span class='close'>x</span><br /><span class='another'>Add another</span>");
    $(this).html("<span class='another'>Add another</span>");
	clone = $(this).clone(true);
	alert('click');
  });
  $('dl').delegate('.another', 'click', function() {
    //e.stopPropagation();
	alert('another');
    $(this).parent().parent().append(clone);
  });
   
});
</script>
</head>
    
<body>
<dl>
  <dt>Phone</dt>
  <dd class='dd'>Add a phone number<span class='another'>sfsfsfsfsf</span></dd>
</dl>
</body>
</html>
这样不行呢?[/quote] 在不行的这段代码中,实际执行如下: 点击another,click事件开始冒泡==>another并没有绑定click事件函数所以冒泡到dd==>因为dd被绑定了click事件函数,所以dd的click函数开始执行(执行内容为将当前dd内的html替换成新的html->'<span class='another'>Add another</span>',然后把dd节点复制给变量clone,最后弹出字符串“click”)==>dd的监听函数执行完后,click继续冒泡到dl==>dl上虽然绑定了click函数,但是是通过delegate绑定的,所以需要先检查你最开始点击的那个元素是否匹配选择器‘.another’,但是:此时你点击的那个another早已不存在了,因为dd的监听函数执行时已经重写了dd内的html(你可以理解为删除了原来的another然后又新添加了一个another),即使新写的another和你点击的那个another是一模一样的,他们两个也是毫无关系彼此独立的。之前讲过‘匹配’这个条件必需满足才会触发事件函数,现在既然元素已经不存在,delegate关于是否匹配的的检查也就无法进行,最终dl上的函数也就无法被触发,即无法弹出another。 唉 讲的我口干舌燥~~~求结贴~
阿鱼 2013-09-13
  • 打赏
  • 举报
回复
引用 20 楼 veryhunger 的回复:
[quote=引用 19 楼 qwklove 的回复:] 不知道楼主有没有已经把冒泡问题解决掉~ 其实,楼主这段代码: 1.最开始由于delegate的机制存在冒泡问题,所以无法添加新dd; 2.把冒泡修改好后,楼主可能会发现:还是无法添加新dd; 不知道楼主现在是1,2中哪个情况: 如果是1,那么首先要把冒泡问题解决掉,比如把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...)。 如果是2,那么问题就在于clone()这个方法。 ps:虽在本帖回复,但测试仍然用的是原帖楼主的代码。
属于情况二,你说的把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...) 我感觉不理解 $('dl').delegate('.another'...)是给dl下的所有.another添加代理事件句柄,包括后来添加的 可是改成$('dl dd').delegate('.another'...), 由于开始页面只有一个dd标签,也就只给第一个dd下的.another添加了代理事件句柄 后来添加的dd下的.another应该添加不到吧?[/quote] (1)用delegate进行绑定,不管元素是已经存在在页面上的还是后来动态添加的,都会被绑定。 这也正是delegate绑定和bind绑定的区别之处,delegate自jquery-1.7以上就已经被on代替了,on与delegate是同效的。 (2)拿你的代码来讲,增加一个新dd后,再点击新dd中的another无效和delegate是无关的,问题在于clone这个方法。你可以把clone=$(this).clone(true);换成clone='<p>content</p>',即把clone赋值为html字符串,然后再点击another,和之前的代码运行情况对比一下。 (3)至于clone这个方法的什么特性引发的another无效,楼主可以自行google一下,单独测测clone这个方法。
  • 打赏
  • 举报
回复
引用 23 楼 qwklove 的回复:
[quote=引用 22 楼 veryhunger 的回复:] [quote=引用 21 楼 qwklove 的回复:] [quote=引用 20 楼 veryhunger 的回复:] [quote=引用 19 楼 qwklove 的回复:] 不知道楼主有没有已经把冒泡问题解决掉~ 其实,楼主这段代码: 1.最开始由于delegate的机制存在冒泡问题,所以无法添加新dd; 2.把冒泡修改好后,楼主可能会发现:还是无法添加新dd; 不知道楼主现在是1,2中哪个情况: 如果是1,那么首先要把冒泡问题解决掉,比如把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...)。 如果是2,那么问题就在于clone()这个方法。 ps:虽在本帖回复,但测试仍然用的是原帖楼主的代码。
属于情况二,你说的把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...) 我感觉不理解 $('dl').delegate('.another'...)是给dl下的所有.another添加代理事件句柄,包括后来添加的 可是改成$('dl dd').delegate('.another'...), 由于开始页面只有一个dd标签,也就只给第一个dd下的.another添加了代理事件句柄 后来添加的dd下的.another应该添加不到吧?[/quote] (1)用delegate进行绑定,不管元素是已经存在在页面上的还是后来动态添加的,都会被绑定。 这也正是delegate绑定和bind绑定的区别之处,delegate自jquery-1.7以上就已经被on代替了,on与delegate是同效的。 (2)拿你的代码来讲,增加一个新dd后,再点击新dd中的another无效和delegate是无关的,问题在于clone这个方法。你可以把clone=$(this).clone(true);换成clone='<p>content</p>',即把clone赋值为html字符串,然后再点击another,和之前的代码运行情况对比一下。 (3)至于clone这个方法的什么特性引发的another无效,楼主可以自行google一下,单独测测clone这个方法。[/quote]
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript'>
/*$(function() {
	$('dl').delegate('.another', 'click', function() {
		alert('dd');
	});
	$('button').click(function() {
		$('dl').append($("<dd><div class='another'>gggggggggggggg</div></dd>"));
	});
});*/
$(function() {
	$('dl dd').delegate('.another', 'click', function() {
		alert('dd');
	});
	$('button').click(function() {
		$('dl').append($("<dd><div class='another'>gggggggggggggg</div></dd>"));
	});
});
</script>
</head>

<body>
<dl>
	<dd>
		<div class='another'>sfsfsf</div>
	</dd>
</dl>
<button>按钮</button>
</body>
</html>
我的疑惑是给dd click如果不用代理就只能给一个dd加 click 如果用代理 即$('dl')给所有dl下的dd加click,那么后来添加的.another也被添加了事件了 我这个例子证明了这个问题 如果用$('dl dd')的话,那么通过button添加的.another就得不到代理事件了[/quote] (1)你已经基本得出结论了~ 还是delegate的问题:

$('选择器A').delegate('选择器B','eventType',function(){...});
选择器A只针对页面上已存在的元素,也就是说delegate只对执行时页面上已存在的元素进行绑定,不负责执行后又动态添加的元素。 (2)用你的代码来说,就是:

$('dl dd').delegate('.another', 'click', function() {
        alert('dd');
    });
这一句在执行的时候,‘.another’在页面上存在与否不重要,但是‘dl dd’必须是存在的(如果不存在匹配‘dl dd’的元素,那么这个delegate的绑定就相当于给不存在的元素进行绑定--无效且毫无意义;如果存在,则对每个匹配的元素进行绑定)。 而你的代码这一句在执行的时候,html中只有一个dd,所以只给这个dd进行了绑定。至于后面新添加的dd,因为这些dd在delegate执行的时候是不存在的,所以不会被绑定事件函数。 改成$('dl')为什么都会弹出,相信楼主也已经明白了吧~[/quote] 还有个地方不明白
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript'>
$(function() {
	$('#divId').click(function() {
		alert('click');
		//$('#di').attr('id', 'divd');
		$(this).html("<div class='di'>sfsfsfsfsfsfsfsf</div>");
	});
	$(document).delegate('.di', 'click', function() {
		alert('delegate');
	});
});
</script>
</head>

<body>
<div id='divId'>
	<div class='di'>
		ljljljsfsfsf
	</div>
</div>
</body>
</html>
为什么这样可以
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type='text/css'>
dl dt { width:100px; float:left; }
dl dd { margin-left:200px; }
</style>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>  
<script type='text/javascript'>
var clone;
$(function() {
  $('dl dd').click(function() {
    //$(this).html("<input type='text' /> <select><option value='Work'>Work</option></select> <span class='close'>x</span><br /><span class='another'>Add another</span>");
    $(this).html("<span class='another'>Add another</span>");
	clone = $(this).clone(true);
	alert('click');
  });
  $('dl').delegate('.another', 'click', function() {
    //e.stopPropagation();
	alert('another');
    $(this).parent().parent().append(clone);
  });
   
});
</script>
</head>
    
<body>
<dl>
  <dt>Phone</dt>
  <dd class='dd'>Add a phone number<span class='another'>sfsfsfsfsf</span></dd>
</dl>
</body>
</html>
这样不行呢?
  • 打赏
  • 举报
回复
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript'>
$(function() {
	$('#divId').click(function() {
		alert('divId');
	});
	$(document).delegate('#di', 'click', function(e) {
		e.stopPropagation();
		alert('#di');
	});
});
</script>
</head>

<body>
<div id='divId'>
	<div id='di'>
		ljljj
	</div>
</div>
</body>
</html>
在委托事件中,若想阻止事件冒泡,也必需得找到匹配元素
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type='text/css'>
dl dt { width:100px; float:left; }
dl dd { margin-left:200px; }
</style>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>  
<script type='text/javascript'>
var clone;
$(function() {
  $('dl dd').click(function() {
    $(this).html("<input type='text' /> <select><option value='Work'>Work</option></select> <span class='close'>x</span><br /><span class='another'>Add another</span>");
    clone = $(this).clone(true);
	alert('click');
  });
  $('dl').delegate('.another', 'click', function(e) {
    e.stopPropagation();
	alert('another');
    $(this).parent().parent().append(clone);
  });
   
});
</script>
</head>
    
<body>
<dl>
  <dt>Phone</dt>
  <dd class='dd'>Add a phone number</dd>
</dl>
</body>
</html>
上面的先执行的始终是dd的click事件 当执行了dd的click事件了,这时target已经被改变了,所以冒泡事件不会被执行了
  • 打赏
  • 举报
回复
引用 23 楼 qwklove 的回复:
[quote=引用 22 楼 veryhunger 的回复:] [quote=引用 21 楼 qwklove 的回复:] [quote=引用 20 楼 veryhunger 的回复:] [quote=引用 19 楼 qwklove 的回复:] 不知道楼主有没有已经把冒泡问题解决掉~ 其实,楼主这段代码: 1.最开始由于delegate的机制存在冒泡问题,所以无法添加新dd; 2.把冒泡修改好后,楼主可能会发现:还是无法添加新dd; 不知道楼主现在是1,2中哪个情况: 如果是1,那么首先要把冒泡问题解决掉,比如把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...)。 如果是2,那么问题就在于clone()这个方法。 ps:虽在本帖回复,但测试仍然用的是原帖楼主的代码。
属于情况二,你说的把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...) 我感觉不理解 $('dl').delegate('.another'...)是给dl下的所有.another添加代理事件句柄,包括后来添加的 可是改成$('dl dd').delegate('.another'...), 由于开始页面只有一个dd标签,也就只给第一个dd下的.another添加了代理事件句柄 后来添加的dd下的.another应该添加不到吧?[/quote] (1)用delegate进行绑定,不管元素是已经存在在页面上的还是后来动态添加的,都会被绑定。 这也正是delegate绑定和bind绑定的区别之处,delegate自jquery-1.7以上就已经被on代替了,on与delegate是同效的。 (2)拿你的代码来讲,增加一个新dd后,再点击新dd中的another无效和delegate是无关的,问题在于clone这个方法。你可以把clone=$(this).clone(true);换成clone='<p>content</p>',即把clone赋值为html字符串,然后再点击another,和之前的代码运行情况对比一下。 (3)至于clone这个方法的什么特性引发的another无效,楼主可以自行google一下,单独测测clone这个方法。[/quote]
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript'>
/*$(function() {
	$('dl').delegate('.another', 'click', function() {
		alert('dd');
	});
	$('button').click(function() {
		$('dl').append($("<dd><div class='another'>gggggggggggggg</div></dd>"));
	});
});*/
$(function() {
	$('dl dd').delegate('.another', 'click', function() {
		alert('dd');
	});
	$('button').click(function() {
		$('dl').append($("<dd><div class='another'>gggggggggggggg</div></dd>"));
	});
});
</script>
</head>

<body>
<dl>
	<dd>
		<div class='another'>sfsfsf</div>
	</dd>
</dl>
<button>按钮</button>
</body>
</html>
我的疑惑是给dd click如果不用代理就只能给一个dd加 click 如果用代理 即$('dl')给所有dl下的dd加click,那么后来添加的.another也被添加了事件了 我这个例子证明了这个问题 如果用$('dl dd')的话,那么通过button添加的.another就得不到代理事件了[/quote] (1)你已经基本得出结论了~ 还是delegate的问题:

$('选择器A').delegate('选择器B','eventType',function(){...});
选择器A只针对页面上已存在的元素,也就是说delegate只对执行时页面上已存在的元素进行绑定,不负责执行后又动态添加的元素。 (2)用你的代码来说,就是:

$('dl dd').delegate('.another', 'click', function() {
        alert('dd');
    });
这一句在执行的时候,‘.another’在页面上存在与否不重要,但是‘dl dd’必须是存在的(如果不存在匹配‘dl dd’的元素,那么这个delegate的绑定就相当于给不存在的元素进行绑定--无效且毫无意义;如果存在,则对每个匹配的元素进行绑定)。 而你的代码这一句在执行的时候,html中只有一个dd,所以只给这个dd进行了绑定。至于后面新添加的dd,因为这些dd在delegate执行的时候是不存在的,所以不会被绑定事件函数。 改成$('dl')为什么都会弹出,相信楼主也已经明白了吧~[/quote] 在不理解jquery的delegate源码的情况下,经过大家无私帮助,自己基本已经理解
var clone;
$(function() {
  $('dl dd').click(function() {
    $(this).html("<input type='text' /> <select><option value='Work'>Work</option></select> <span class='close'>x</span><br /><span class='another'>Add another</span>");
    clone = $(this).clone(true);
	alert('click');
  });
  $('dl dd').delegate('.another', 'click', function(e) {
    //e.stopPropagation();
	alert('another');
    $(this).parent().parent().append(clone);
  });
   
});
$('dl dd').click(... 是给页面上仅存在的一个dd加click事件 事件中有一个关键就是clone=$(this).clone(true);加了true不仅把页面上仅存的那个dd的click事件给复制了,而且把dd的代理事件也复制了 $('dl dd').delegate('.another', 'click',...是给页面上存在的那个dd加代理事件 第一次点击.another事件冒泡到dd就执行代理事件,接着执行绑定给dd的事件 第二次点击.another,由于已经dd保存事件了,包括代理事件,即$('dd').delegate(...所以还会执行 当加了e.stopPropagation();后代理事件照样执行,但是dd的click事件却被阻止了,也就是clone不能被重新赋值了, 这里clone每次被append进去后再append就没效果了,必需被重新赋值 关于事件委托的弊端
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript'>
$(function() {
	$('#divId').click(function() {
		alert('divId');
	});
	$(document).delegate('#di', 'click', function() {
		alert('#di');
	});
});
</script>
</head>

<body>
<div id='divId'>
	<div id='di'>
		ljljj
	</div>
</div>
</body>
</html>
这里明明点击了最内层的di,可是先弹出的是divId 这说明,执行委托事件的条件是必需冒泡到匹配元素 关于先执行委托事件还是直接绑定的事件 先执行直接绑定的事件
阿鱼 2013-09-13
  • 打赏
  • 举报
回复
引用 22 楼 veryhunger 的回复:
[quote=引用 21 楼 qwklove 的回复:] [quote=引用 20 楼 veryhunger 的回复:] [quote=引用 19 楼 qwklove 的回复:] 不知道楼主有没有已经把冒泡问题解决掉~ 其实,楼主这段代码: 1.最开始由于delegate的机制存在冒泡问题,所以无法添加新dd; 2.把冒泡修改好后,楼主可能会发现:还是无法添加新dd; 不知道楼主现在是1,2中哪个情况: 如果是1,那么首先要把冒泡问题解决掉,比如把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...)。 如果是2,那么问题就在于clone()这个方法。 ps:虽在本帖回复,但测试仍然用的是原帖楼主的代码。
属于情况二,你说的把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...) 我感觉不理解 $('dl').delegate('.another'...)是给dl下的所有.another添加代理事件句柄,包括后来添加的 可是改成$('dl dd').delegate('.another'...), 由于开始页面只有一个dd标签,也就只给第一个dd下的.another添加了代理事件句柄 后来添加的dd下的.another应该添加不到吧?[/quote] (1)用delegate进行绑定,不管元素是已经存在在页面上的还是后来动态添加的,都会被绑定。 这也正是delegate绑定和bind绑定的区别之处,delegate自jquery-1.7以上就已经被on代替了,on与delegate是同效的。 (2)拿你的代码来讲,增加一个新dd后,再点击新dd中的another无效和delegate是无关的,问题在于clone这个方法。你可以把clone=$(this).clone(true);换成clone='<p>content</p>',即把clone赋值为html字符串,然后再点击another,和之前的代码运行情况对比一下。 (3)至于clone这个方法的什么特性引发的another无效,楼主可以自行google一下,单独测测clone这个方法。[/quote]
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
<script type='text/javascript'>
/*$(function() {
	$('dl').delegate('.another', 'click', function() {
		alert('dd');
	});
	$('button').click(function() {
		$('dl').append($("<dd><div class='another'>gggggggggggggg</div></dd>"));
	});
});*/
$(function() {
	$('dl dd').delegate('.another', 'click', function() {
		alert('dd');
	});
	$('button').click(function() {
		$('dl').append($("<dd><div class='another'>gggggggggggggg</div></dd>"));
	});
});
</script>
</head>

<body>
<dl>
	<dd>
		<div class='another'>sfsfsf</div>
	</dd>
</dl>
<button>按钮</button>
</body>
</html>
我的疑惑是给dd click如果不用代理就只能给一个dd加 click 如果用代理 即$('dl')给所有dl下的dd加click,那么后来添加的.another也被添加了事件了 我这个例子证明了这个问题 如果用$('dl dd')的话,那么通过button添加的.another就得不到代理事件了[/quote] (1)你已经基本得出结论了~ 还是delegate的问题:

$('选择器A').delegate('选择器B','eventType',function(){...});
选择器A只针对页面上已存在的元素,也就是说delegate只对执行时页面上已存在的元素进行绑定,不负责执行后又动态添加的元素。 (2)用你的代码来说,就是:

$('dl dd').delegate('.another', 'click', function() {
        alert('dd');
    });
这一句在执行的时候,‘.another’在页面上存在与否不重要,但是‘dl dd’必须是存在的(如果不存在匹配‘dl dd’的元素,那么这个delegate的绑定就相当于给不存在的元素进行绑定--无效且毫无意义;如果存在,则对每个匹配的元素进行绑定)。 而你的代码这一句在执行的时候,html中只有一个dd,所以只给这个dd进行了绑定。至于后面新添加的dd,因为这些dd在delegate执行的时候是不存在的,所以不会被绑定事件函数。 改成$('dl')为什么都会弹出,相信楼主也已经明白了吧~
阿鱼 2013-09-12
  • 打赏
  • 举报
回复
~ 在原帖已回复 楼主注意查看哦~~
  • 打赏
  • 举报
回复
顶。。。。。。
  • 打赏
  • 举报
回复
引用 19 楼 qwklove 的回复:
不知道楼主有没有已经把冒泡问题解决掉~ 其实,楼主这段代码: 1.最开始由于delegate的机制存在冒泡问题,所以无法添加新dd; 2.把冒泡修改好后,楼主可能会发现:还是无法添加新dd; 不知道楼主现在是1,2中哪个情况: 如果是1,那么首先要把冒泡问题解决掉,比如把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...)。 如果是2,那么问题就在于clone()这个方法。 ps:虽在本帖回复,但测试仍然用的是原帖楼主的代码。
属于情况二,你说的把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...) 我感觉不理解 $('dl').delegate('.another'...)是给dl下的所有.another添加代理事件句柄,包括后来添加的 可是改成$('dl dd').delegate('.another'...), 由于开始页面只有一个dd标签,也就只给第一个dd下的.another添加了代理事件句柄 后来添加的dd下的.another应该添加不到吧?
阿鱼 2013-09-12
  • 打赏
  • 举报
回复
不知道楼主有没有已经把冒泡问题解决掉~ 其实,楼主这段代码: 1.最开始由于delegate的机制存在冒泡问题,所以无法添加新dd; 2.把冒泡修改好后,楼主可能会发现:还是无法添加新dd; 不知道楼主现在是1,2中哪个情况: 如果是1,那么首先要把冒泡问题解决掉,比如把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...)。 如果是2,那么问题就在于clone()这个方法。 ps:虽在本帖回复,但测试仍然用的是原帖楼主的代码。
fzfei2 2013-09-12
  • 打赏
  • 举报
回复
把 click 改成 mouseup 就可以添加了 $('dl').delegate('.another', 'mouseup', function(e) { e.stopPropagation(); $(this).parent().parent().append(clone); });
conanhhy 2013-09-12
  • 打赏
  • 举报
回复
引用 16 楼 veryhunger 的回复:
[quote=引用 14 楼 conanhhy 的回复:] [quote=引用 7 楼 veryhunger 的回复:] [quote=引用 6 楼 conanhhy 的回复:] LZ,下面的这段代码改下:

$('dl dd').delegate('.another', 'click', function(e) {
    //e.stopPropagation();
    $(this).parent().parent().append(clone);
  });
为什么这样就可以了呢?[/quote] LZ,关于之前提到的问题,我调查了下。 主要问题还是在于delegate机制上,下面是关于在delegate内使用e.stopPropagation的说明 使用事件委托时,如果注册到目标元素上的其他事件处理程序使用.stopPropagation()阻止了事件传播, 那么事件委托就会失效。[/quote] 麻烦您解释下13楼的问题,感谢你热心回答[/quote] LZ,关于这个问题的解答, @qwklove解释得很详细,很清楚了。 正如我15楼所说的,简单来说的话: 点击".another"后,执行了e.stopPropagation(),从而阻止了冒泡,但同时也使得委托失效。 因此再次点击".another"后,由于委托的失效,导致".another"无法正常被执行 基本意思和@qwklove是一致的。详细的LZ可以仔细看看@qwklove的回复
  • 打赏
  • 举报
回复
引用 14 楼 conanhhy 的回复:
[quote=引用 7 楼 veryhunger 的回复:] [quote=引用 6 楼 conanhhy 的回复:] LZ,下面的这段代码改下:

$('dl dd').delegate('.another', 'click', function(e) {
    //e.stopPropagation();
    $(this).parent().parent().append(clone);
  });
为什么这样就可以了呢?[/quote] LZ,关于之前提到的问题,我调查了下。 主要问题还是在于delegate机制上,下面是关于在delegate内使用e.stopPropagation的说明 使用事件委托时,如果注册到目标元素上的其他事件处理程序使用.stopPropagation()阻止了事件传播, 那么事件委托就会失效。[/quote] 麻烦您解释下13楼的问题,感谢你热心回答
  • 打赏
  • 举报
回复
引用 14 楼 conanhhy 的回复:
[quote=引用 7 楼 veryhunger 的回复:] [quote=引用 6 楼 conanhhy 的回复:] LZ,下面的这段代码改下:

$('dl dd').delegate('.another', 'click', function(e) {
    //e.stopPropagation();
    $(this).parent().parent().append(clone);
  });
为什么这样就可以了呢?[/quote] LZ,关于之前提到的问题,我调查了下。 主要问题还是在于delegate机制上,下面是关于在delegate内使用e.stopPropagation的说明 使用事件委托时,如果注册到目标元素上的其他事件处理程序使用.stopPropagation()阻止了事件传播, 那么事件委托就会失效。[/quote] 哦,把我愁的皱纹都多了
conanhhy 2013-09-12
  • 打赏
  • 举报
回复
引用 7 楼 veryhunger 的回复:
[quote=引用 6 楼 conanhhy 的回复:] LZ,下面的这段代码改下:

$('dl dd').delegate('.another', 'click', function(e) {
    //e.stopPropagation();
    $(this).parent().parent().append(clone);
  });
为什么这样就可以了呢?[/quote] LZ,关于之前提到的问题,我调查了下。 主要问题还是在于delegate机制上,下面是关于在delegate内使用e.stopPropagation的说明 使用事件委托时,如果注册到目标元素上的其他事件处理程序使用.stopPropagation()阻止了事件传播, 那么事件委托就会失效。
  • 打赏
  • 举报
回复
引用 12 楼 qwklove 的回复:
~ 在原帖已回复 楼主注意查看哦~~
可是有一个地方不明白 第一次$('dl dd').click这句已经给绑定一个事件,没用代理,也就是页面中只有一个dd被绑定 然后加代理$('dl').delegate('.another', 'click', functtion() {});按说页面所有的.another一点击,就可以给页面append一个dd元素啊,在点击新的dd里面的.another还可以再加新的,为什么点击.another没反应呢?
conanhhy 2013-09-11
  • 打赏
  • 举报
回复
size是方法,不是属性。应该写.size()
  • 打赏
  • 举报
回复
引用 8 楼 conanhhy 的回复:
[quote=引用 7 楼 veryhunger 的回复:] [quote=引用 6 楼 conanhhy 的回复:] LZ,下面的这段代码改下:

$('dl dd').delegate('.another', 'click', function(e) {
    //e.stopPropagation();
    $(this).parent().parent().append(clone);
  });
为什么这样就可以了呢?[/quote] 之所以找到这个地方,是因为发现一个现象。就是点击"Add another"后,新生成的"Add another"点击没有任何触发。但是有两种情况可以让其触发: 1. 点击"x",之后再操作,新生成的"Add another"就可以触发了 2. 点击下拉列表,之后点击"Add another"同样可以触发 因此,之后是个人猜测,感觉事件不是没有触发,而是被阻止了。然后通过这个思路发现那句代码有问题[/quote]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type='text/css'>
dl dt { width:100px; float:left; }
dl dd { margin-left:200px; }
</style>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>  

</head>
 
<body>
<dl>
  <dt>Phone</dt>
  <dd class='dd'>Add a phone number</dd>
</dl>
<div></div>
<script type='text/javascript'>
var clone,k = 0;
$(function() {
  $('dl dd').click(function() {
    $(this).html("<input type='text' /> <select><option value='Work'>Work</option></select> <span class='close'>x</span><br /><span class='another'>Add another</span>");
	//$(this).off('click');
	$(this).css('background-color', 'red');
    clone = $(this).clone(true);
	console.log($('dl dd').size + '?');
	k++;
	$('div').html(k);
  });
  /*$('.close').live('click', function() {
    $(this).parent().html('Add a phone number');
  });*/
  $('dl dd').delegate('.close', 'click', function(e) {
	//$(this).parent().html('Add a phone number');
	e.stopPropagation();
	$(this).parent().html('Add a phone number');
  });
  /*$('dl dd input').keydown(function() {
    $('this').parent().append("<br /><span class='another'>Add another</span>");
  });*/
  $('dl dd').delegate('input', 'click', function(e) {
	e.stopPropagation();
  });
  /*$('.another').live('click', function() {
    $(this).parent().parent().append(clone);
  });*/
  $('dl dd').delegate('.another', 'click', function(e) {
	//e.stopPropagation();
	console.log('h');
	$(this).parent().parent().append(clone);
  });

});
</script>
</body>
</html>
应该只给一个dd绑定事件吧 获得大小为什么显示函数?
加载更多回复(8)

87,923

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧