5

这是一段简单的代码:

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 从“关闭”更改为“扩展”吗?我该如何解决这个问题?

我试过了:

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

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

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

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

这也行不通。

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

谢谢。

4

3 回答 3

10

在这种情况下,您需要两个委托事件(又名实时)处理程序。因为,您在两个ids 之间切换,并且这种切换使两个ids 对于 DOM 都是动态的。

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

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

演示

笔记

由于live()弃用,因此不live()用于.on()委托事件处理。

于 2012-08-16T19:41:30.410 回答
3

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

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

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

  1. 注册的点击事件#close,处理程序触发。
  2. #close改为#expand
  3. click 事件使 DOM 冒泡,直到它到达document
  4. 点击事件注册document,文档看到目标元素的ID是#expand,并触发事件处理程序

解决此问题的方法是添加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 挂钩

于 2012-08-16T19:44:48.950 回答
0

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

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

例如。

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

这样就没有必要改变你的身份证了。

于 2012-08-16T19:42:58.027 回答