首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > JavaScript >

关于jquery delegate的迷惑

2013-09-15 
关于jquery delegate的疑惑!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www

关于jquery delegate的疑惑

<!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为什么不添加


[解决办法]
LZ,下面的代码应该改下:


$('dl dd').delegate('.another', 'click', function(e) {
    e.stopPropagation();
    $(this).parent().parent().append(clone);
  });


这样就会触发了
[解决办法]
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

不知道楼主有没有已经把冒泡问题解决掉~

其实,楼主这段代码:
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应该添加不到吧?


(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这个方法。
<!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就得不到代理事件了


(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')为什么都会弹出,相信楼主也已经明白了吧~

还有个地方不明白
<!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>


这样不行呢?


在不行的这段代码中,实际执行如下:
点击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。

关于jquery delegate的迷惑 讲的我口干舌燥~~~求结贴~

热点排行