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

解决方案 »

  1.   

    LZ,下面的代码应该改下:$('dl dd').delegate('.another', 'click', function(e) {
        e.stopPropagation();
        $(this).parent().parent().append(clone);
      });
    这样就会触发了
      

  2.   

    不会啊,我本地试过了。点击后可以触发
    浏览器,IE和CHROME都可以的<!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 dd').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>这是我修改的代码
      

  3.   

    点击第二个add another就不行了
      

  4.   

    LZ,下面的这段代码改下:$('dl dd').delegate('.another', 'click', function(e) {
        //e.stopPropagation();
        $(this).parent().parent().append(clone);
      });
      

  5.   

    为什么这样就可以了呢?
    之所以找到这个地方,是因为发现一个现象。就是点击"Add another"后,新生成的"Add another"点击没有任何触发。但是有两种情况可以让其触发:
    1. 点击"x",之后再操作,新生成的"Add another"就可以触发了
    2. 点击下拉列表,之后点击"Add another"同样可以触发因此,之后是个人猜测,感觉事件不是没有触发,而是被阻止了。然后通过这个思路发现那句代码有问题
      

  6.   

    为什么这样就可以了呢?
    之所以找到这个地方,是因为发现一个现象。就是点击"Add another"后,新生成的"Add another"点击没有任何触发。但是有两种情况可以让其触发:
    1. 点击"x",之后再操作,新生成的"Add another"就可以触发了
    2. 点击下拉列表,之后点击"Add another"同样可以触发因此,之后是个人猜测,感觉事件不是没有触发,而是被阻止了。然后通过这个思路发现那句代码有问题<!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绑定事件吧
    获得大小为什么显示函数?
      

  7.   

    size是方法,不是属性。应该写.size()
      

  8.   

    可是有一个地方不明白
    第一次$('dl dd').click这句已经给绑定一个事件,没用代理,也就是页面中只有一个dd被绑定
    然后加代理$('dl').delegate('.another', 'click', functtion() {});按说页面所有的.another一点击,就可以给页面append一个dd元素啊,在点击新的dd里面的.another还可以再加新的,为什么点击.another没反应呢?
      

  9.   

    为什么这样就可以了呢?
    LZ,关于之前提到的问题,我调查了下。
    主要问题还是在于delegate机制上,下面是关于在delegate内使用e.stopPropagation的说明
    使用事件委托时,如果注册到目标元素上的其他事件处理程序使用.stopPropagation()阻止了事件传播,
    那么事件委托就会失效。
      

  10.   

    为什么这样就可以了呢?
    LZ,关于之前提到的问题,我调查了下。
    主要问题还是在于delegate机制上,下面是关于在delegate内使用e.stopPropagation的说明
    使用事件委托时,如果注册到目标元素上的其他事件处理程序使用.stopPropagation()阻止了事件传播,
    那么事件委托就会失效。

    哦,把我愁的皱纹都多了
      

  11.   

    为什么这样就可以了呢?
    LZ,关于之前提到的问题,我调查了下。
    主要问题还是在于delegate机制上,下面是关于在delegate内使用e.stopPropagation的说明
    使用事件委托时,如果注册到目标元素上的其他事件处理程序使用.stopPropagation()阻止了事件传播,
    那么事件委托就会失效。

    麻烦您解释下13楼的问题,感谢你热心回答
      

  12.   

    为什么这样就可以了呢?
    LZ,关于之前提到的问题,我调查了下。
    主要问题还是在于delegate机制上,下面是关于在delegate内使用e.stopPropagation的说明
    使用事件委托时,如果注册到目标元素上的其他事件处理程序使用.stopPropagation()阻止了事件传播,
    那么事件委托就会失效。

    麻烦您解释下13楼的问题,感谢你热心回答
    LZ,关于这个问题的解答, @qwklove解释得很详细,很清楚了。
    正如我15楼所说的,简单来说的话:
    点击".another"后,执行了e.stopPropagation(),从而阻止了冒泡,但同时也使得委托失效。
    因此再次点击".another"后,由于委托的失效,导致".another"无法正常被执行基本意思和@qwklove是一致的。详细的LZ可以仔细看看@qwklove的回复
      

  13.   

    把 click 改成 mouseup 就可以添加了
      $('dl').delegate('.another', 'mouseup', function(e) {
        e.stopPropagation();
        $(this).parent().parent().append(clone);
      });
      

  14.   

    不知道楼主有没有已经把冒泡问题解决掉~其实,楼主这段代码:
    1.最开始由于delegate的机制存在冒泡问题,所以无法添加新dd;
    2.把冒泡修改好后,楼主可能会发现:还是无法添加新dd;不知道楼主现在是1,2中哪个情况:
    如果是1,那么首先要把冒泡问题解决掉,比如把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...)。
    如果是2,那么问题就在于clone()这个方法。ps:虽在本帖回复,但测试仍然用的是原帖楼主的代码。
      

  15.   

    属于情况二,你说的把$('dl').delegate('.another'...)换成$('dl dd').delegate('.another'...)
    我感觉不理解
    $('dl').delegate('.another'...)是给dl下的所有.another添加代理事件句柄,包括后来添加的
    可是改成$('dl dd').delegate('.another'...),
    由于开始页面只有一个dd标签,也就只给第一个dd下的.another添加了代理事件句柄
    后来添加的dd下的.another应该添加不到吧?
      

  16.   

    属于情况二,你说的把$('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这个方法。
      

  17.   

    属于情况二,你说的把$('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就得不到代理事件了
      

  18.   

    属于情况二,你说的把$('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')为什么都会弹出,相信楼主也已经明白了吧~
      

  19.   

    属于情况二,你说的把$('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')为什么都会弹出,相信楼主也已经明白了吧~
    在不理解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
    这说明,执行委托事件的条件是必需冒泡到匹配元素
    关于先执行委托事件还是直接绑定的事件
    先执行直接绑定的事件
      

  20.   

    <!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已经被改变了,所以冒泡事件不会被执行了
      

  21.   

    属于情况二,你说的把$('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>
    这样不行呢?
      

  22.   

    属于情况二,你说的把$('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。唉 讲的我口干舌燥~~~求结贴~
      

  23.   

    属于情况二,你说的把$('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。唉 讲的我口干舌燥~~~求结贴~

    好吧,感谢大家了