2011-03-27 204 views
2

我似乎无法弄清楚为什么只有第一个元素调用显示警报的事件处理程序。我发现堆栈溢出的其他类似问题与使用ID而不是类有关,但这不是我的问题。jQuery事件处理程序只适用于第一个元素

当我点击第一个元素旁边的'x'时,它将按预期方式显示警报,但未能为通过追加按钮动态添加的其他元素执行此操作。

这里有一个最小的,但完整的例子:

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

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

为什么只有第一个元素是工作的原因是因为当时

<!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> 

回答

2

变化click事件附加,只有一个<a>榄仁nt在页面上。您需要明确地将点击事件处理程序添加到每个创建的锚点,或者使用实时事件。阅读有关live事件处理程序的更多信息。

+0

就是这样。我正在学习jQuery,并被这个问题困扰了几天。感谢您提供清晰,简洁的答案。 – Raj 2011-03-27 14:18:18

+0

'.live()'在1.7中被弃用,即使在使用旧版jQuery的项目中也不鼓励它的使用。 – saluce 2012-07-30 16:00:41

+0

@saluce - 好点,但是当我写这个答案的时候,“活着”真是充满活力和繁荣。 – Anurag 2012-07-30 17:32:42

2

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

可以使用livedelegate功能,或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之后也没有一个,而是两个维护版本。
  2. 您正在使用两个独立的ready调用,首先是显式调用,然后是隐式调用(您的$传入函数)。只有一个是必要的。
  3. 强烈推荐不是依靠分号插入,它是魔鬼的产生。用分号结束语句,以确保脚本可以缩小/压缩/打包,仅仅因为解释者有时会猜错。
+0

感谢您的示例。实际上,我在我的代码中使用了最新版本的jQuery,但是我发现了一些在线的东西,显然有点旧,它使用了当时的版本,这就是我最基本的例子。感谢您提及两个准备好的调用 - 我只是在加快jQuery并欣赏指针。我来自Python,语义上有意义的空白是常态---需要养成用分号结束语句的习惯。再次感谢! – Raj 2011-03-27 15:28:55

+0

@Raj:不用担心,希望有帮助!最好的, – 2011-03-27 15:40:13

+0

'.live()'不推荐使用1.7,建议在1.7之前使用'.on()',1.7之前使用'.delegate()'。 – saluce 2012-07-30 15:59:27

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"); }); 
相关问题