jQuery'click'自动触发'live'

时间:2012-08-16 19:38:35

标签: javascript jquery

这是一段简单的代码:

HTML:

<div id="close">Click me</div>

JS代码:

$("#close").click(function(){
    alert("1");
    $(this).attr('id','expand');
});



$("#expand").live('click', function(){
    alert("2");
    $(this).attr('id','close');            
});

问题:当我点击“关闭”时,它也会自动调用live()。请参阅jsfiddle:http://jsfiddle.net/uFJkg/

是因为我将同一元素的id从“close”更改为“expand”吗?我该如何解决这个问题?

我试过了:

 $("#expand").die().live('click', function()

但它不起作用。我尝试了event.stopPropagation(),但这也没有帮助。我尝试使用id为“expand”的单独div并将其隐藏在document.ready上但由于某种原因它也不起作用。

然后我尝试了,因为我读到jQuery 1.7 +中已经弃用了live():

$("#expand").on('click', function(){

这也不行。

有什么想法?我认为一双新鲜的眼睛能够发现我所缺少的东西。

感谢。

3 个答案:

答案 0 :(得分:10)

在这种情况下,您需要委托事件(aka live)处理程序。因为,您在两个id之间进行切换,并且此切换使两个id成为DOM的动态。

$("body").on("click", "#close", function(){
    alert("1");
    $(this).attr('id','expand');
});

$("body").on("click", "#expand", function(){
    alert("2");
    $(this).attr('id','close');            
});

DEMO

注意

由于live() deprecated ,因此使用 .on()代替live() 用于委托事件处理。

答案 1 :(得分:3)

这与live附加事件以及事件冒泡如何工作的方式有关。

.live将事件处理程序附加到document。当文档注册事件时,它会查看该事件的target是什么。如果它匹配传递给.live的选择器,则会触发处理程序。

因此,当您点击#close时,会发生以下情况:

  1. #close上注册的点击事件,处理程序触发。
  2. #close已更改为#expand
  3. 点击事件会在DOM中冒泡,直到达到document
  4. 点击document上的事件记录,文档会看到目标元素的ID为#expand,并触发事件处理程序
  5. 解决此问题的方法是向处理程序添加stopPropagation()

    $("#close").click(function(e){
      if(!e) { e = window.event; }
      e.stopPropagation();
    
      alert("1");
      $(this).attr('id','expand');
    });
    

    但是,我建议不要使用live并查看delegateon来处理委派事件。

    我还建议不要更改ID。如果你想保持关闭/扩展的想法,我会尝试这样的事情:

    <div id="toggler" class="close">Close</div>
    
    $('#toggler').on('click',function() {
        $(this).toggleClass('close').toggleClass('expand');
    });
    

    一个事件处理程序,没有委托,因为它挂钩到永久ID

答案 2 :(得分:0)

首先,更改id的运行时间并不是很干净。你正面临着其中一个结果。

您可以考虑使用数据属性。 jQuery可以通过访问data属性来读取它们。

例如

$("#myObject").data("expanded", true);

通过这种方式,没有必要改变你的身份。