这是一段简单的代码:
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(){
这也不行。
有什么想法?我认为一双新鲜的眼睛能够发现我所缺少的东西。
感谢。
答案 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
时,会发生以下情况:
#close
上注册的点击事件,处理程序触发。#close
已更改为#expand
document
document
上的事件记录,文档会看到目标元素的ID为#expand
,并触发事件处理程序解决此问题的方法是向处理程序添加stopPropagation()
:
$("#close").click(function(e){
if(!e) { e = window.event; }
e.stopPropagation();
alert("1");
$(this).attr('id','expand');
});
但是,我建议不要使用live
并查看delegate
或on
来处理委派事件。
我还建议不要更改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);
通过这种方式,没有必要改变你的身份。