jQuery事件处理程序仅适用于第一个元素

时间:2011-03-27 04:51:43

标签: jquery event-handling

我似乎无法弄清楚为什么只有第一个元素调用显示警报的事件处理程序。我在Stack Overflow上发现了与使用ID而不是类相关的其他类似问题,但这不是我的问题。

当我点击第一个元素旁边的“x”时,它会按预期显示警告,但对于使用追加按钮动态添加的其他元素则无法执行此操作。

这是一个最小但完整的例子:

<!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>test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.0/jquery.min.js"></script>
<script type="text/javascript">

$(document).ready(function() {

   $(function() {

     $(".append").click(function(){

      $('.container').append('<div class="box"></div>')
      $('.box:last').append('<div class="text"><span>ABCDEFG</span><br/></div>')
      $('.box:last').append('<a href="#" class="test">x</a>')

     });

      $("a.test").click(function() {
      alert("works only for the first item in the list");


     });


   });


});

</script>
   <style>
      .box {
          padding:3px;
          margin-bottom:3px;
          border-bottom:2px solid #fff;
          width:550px;
      }
      .box:hover{background-color:#fff;}

      #container {
          position:relative;
      }

      .text {
          float:left;
          width:300px;
          font-size:13px;
      }
      .text span {
          font-size:18px;
          line-height:23px;
          font-weight:700;
      }

   </style>
</head>

<body>

   <div class="container">

     <input type="button" class="append" value="Append">

      <div class="box">
     <div class="text"><span>ABCDEFG</span></div>
     <a href="#" class="test">x</a>
     </div>

   </div>

</body>
</html>

3 个答案:

答案 0 :(得分:2)

更改

$("a.test").click(function() {

$("a.test").live('click', function() {

仅第一个元素工作的原因是因为在附加click事件时,页面上只有一个<a>元素。您需要将click事件处理程序显式添加到创建的每个锚点,或者使用实时事件。阅读有关live事件处理程序的更多信息。

答案 1 :(得分:2)

当您使用bindclickbind("click", ...)的快捷方式)连接事件处理程序时,只会连接已存在的元素。之后添加的新内容不是。

您可以使用 live delegate功能或on功能的委派功能,或在添加时单独连接它们:

  • Live example - 使用最新的jQuery和delegate(您也可以使用on,但我喜欢delegate记录我的意图的方式:

    jQuery(function($) {
    
      $("#theButton").click(function() {
        $("#container").append(
          "<div><a class='test' href='#'>X</a></div>"
        );
      });
    
      $("#container").delegate("a.test", "click", function() {
        alert("Clicked");
      });
    
    });
    
  • Live example - 使用最新的jQuery和on(注意参数的顺序与delegate不同):

    jQuery(function($) {
    
      $("#theButton").click(function() {
        $("#container").append(
          "<div><a class='test' href='#'>X</a></div>"
        );
      });
    
      $("#container").on("click", "a.test", function() {
        alert("Clicked");
      });
    
    });
    
  • Live example - 使用你的jQuery vesion (1.3.0?!)并在添加时将它们连接起来:

    jQuery(function($) {
    
      $("#theButton").click(function() {
        $("<div><a class='test' href='#'>X</a></div>")
          .click(aTestClick)
          .appendTo("#container");
      });
    
      $("a.test").click(aTestClick);
    
      function aTestClick() {
        alert("Clicked");
      }
    
    });
    

偏离主题(略):

  1. jQuery 1.3.0是 九个 版本,已过时两年多了。当前版本(截至2011年3月的原始答案)为1.5.1,即使你想坚持1.3树,1.3.0之后也没有一个只有两个维护版本。 / LI>
  2. 您正在使用两个单独的ready调用,首先是显式调用,然后是隐式调用(您传递函数的$)。只需要一个。
  3. 强烈建议依赖分号插入,它是魔鬼的产物。用分号结束语句,以确保脚本可以缩小/压缩/打包,只是因为解释器有时会猜错。

答案 2 :(得分:2)

您的事件处理程序未添加到随后附加的元素中。有几种方法可以动态附加事件处理程序。对于较新版本的jQuery(1.7+),请将.on()函数与选择器一起使用。

$('.container').on('click', 'a.live', function() { alert("I'm on"); });

旧版本的jQuery没有.on(),因此您可以使用.live()。但是,有一点需要注意,.live()在1.7中已弃用。

$('a.live').live('click', function() { alert("I'm live"); });

即使是jQuery团队建议使用.live()的替代品,无论您使用的jQuery版本如何。对于早于1.7的版本,请使用.delegate()

$('.container').delegate('a.test', 'click', function() { alert("I'm delegated"); });