我想知道在任何情况下使用.click(function {...});
而不是.live('click', function {...});
会更好吗?
从我收集的内容中,live选项似乎是一个更好的选择,因此我几乎在所有情况下都使用它而不是普通的.click(),特别是考虑到我的许多代码是异步加载的。
编辑: 这个问题的另一部分。如果我异步加载所有的javascript,.click仍将拾取已经在dom中的所有元素。正确?
答案 0 :(得分:134)
有时您可能明确希望仅将click处理程序分配给已存在的对象,并以不同方式处理新对象。但更常见的是,现场并不总是有效。它不适用于链式jQuery语句,例如:
$(this).children().live('click',doSomething);
由于事件冒泡DOM树的方式,它需要一个选择器才能正常工作。
编辑:有人刚刚赞成这一点,显然人们仍在关注它。我应该指出live
和bind
都是deprecated。您可以使用.on()
执行这两项操作,IMO是一种更清晰的语法。要替换bind
:
$(selector).on('click', function () {
...
});
并替换live
:
$(document).on('click', selector, function () {
...
});
您可以使用任何包含您监视点击的所有元素的jQuery对象,而不是使用$(document)
,但是当您调用它时,相应的元素必须存在。
答案 1 :(得分:12)
( Note 29/08/2017: live
在很多版本之前已弃用,已在v1.9中删除。delegate
在v3.0中已弃用。在这两种情况下,使用on
的委托签名[也包含在下面]。)
live
通过捕获事件,当它从DOM一直向上冒泡到文档根目录,然后查看源元素时发生。通过捕获元素本身的事件来发生click
。因此,如果您正在使用live
,其中一个祖先元素直接挂钩事件(并阻止它继续冒泡),您将永远不会在元素上看到该事件。通常,最接近事件的元素(点击或其他)首先抓住它,live
和非live
事件的混合可以以微妙的方式改变。
例如:
jQuery(function($) {
$('span').live('click', function() {
display("<tt>live</tt> caught a click!");
});
$('#catcher').click(function() {
display("Catcher caught a click and prevented <tt>live</tt> from seeing it.");
return false;
});
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
});
<div>
<span>Click me</span>
<span>or me</span>
<span>or me</span>
<div>
<span>I'm two levels in</span>
<span>so am I</span>
</div>
<div id='catcher'>
<span>I'm two levels in AND my parent interferes with <tt>live</tt></span>
<span>me too</span>
</div>
</div>
<!-- Using an old version because `live` was removed in v1.9 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
</script>
我建议您尽可能使用delegate
而不是live
,这样您就可以更全面地控制范围;使用delegate
,您可以控制捕获冒泡事件的根元素(例如,live
基本上是delegate
,使用文档根作为根。另外,建议避免(如果可能)让delegate
或live
与非委派的非实时事件处理进行交互。
几年后,您不会使用live
或delegate
;您使用on
的委托签名,但概念仍然相同:事件挂钩在您调用on
的元素上,但只有当后代与后面给出的选择器匹配时才会触发事件名称:
jQuery(function($) {
$(document).on('click', 'span', function() {
display("<tt>live</tt> caught a click!");
});
$('#catcher').click(function() {
display("Catcher caught a click and prevented <tt>live</tt> from seeing it.");
return false;
});
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
});
<div>
<span>Click me</span>
<span>or me</span>
<span>or me</span>
<div>
<span>I'm two levels in</span>
<span>so am I</span>
</div>
<div id='catcher'>
<span>I'm two levels in AND my parent interferes with <tt>live</tt></span>
<span>me too</span>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
答案 2 :(得分:10)
设置事件时,必须存在与.click关联的所有对象。
示例:(在伪代码中)附加可以是$("body").append()
,例如
append('<div id="foo" class="something">...</div>');
$("div.something").click(function(){...});
append('<div id="bar" class="something">...</div>');
点击适用于foo,但不适用于栏
例2:
append('<div id="foo" class="something">...</div>');
$("div.something").live("click",function(){...});
append('<div id="bar" class="something">...</div>');
点击适用于foo和bar
使用.live('点击'...您可以在创建事件后动态添加更多对象,点击事件仍然有效。
答案 3 :(得分:5)
$("#div1").find('button').click(function() {
$('<button />')
.text('BUTTON')
.appendTo('#div1')
})
$("#div2").find('button').live("click", function() {
$('<button />')
.text('BUTTON')
.appendTo('#div2')
})
button {
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div id="div1">
<button>Click</button>
</div>
<div id="div2">
<button>Live</button>
</div>
没有“实时”点击事件仅在您单击第一个按钮时发生,“实时”点击事件也发生在动态生成的按钮上
答案 4 :(得分:4)
如果不动态添加元素,请始终使用click
。
live
通过向文档根添加事件侦听器并侦听冒泡事件来工作。另一种选择是delegate
,它的工作方式相同,但将事件处理程序绑定到指定的元素
这样,事件就不会冒出整个DOM并且更早被捕获。
答案 5 :(得分:3)
.live()。假设您有一个按钮,在页面加载后通过AJAX调用添加。使用.click()无法访问此新按钮,因此您必须使用.live('click')
答案 6 :(得分:1)
由于'live'将处理与当前选择器匹配的未来元素的事件,您可以选择单击,因为您不希望这种情况发生 - 您只想处理当前选定的元素。
另外,我怀疑(虽然没有证据)使用'click'对'live'有一点效率。
利
答案 7 :(得分:1)
据我所知,关键的区别在于live()会一直关注与您正在处理的选择器匹配的新DOM元素,而click()(或bind('click'))会附加事件挂钩和已经完成了。
鉴于你的代码很多是异步加载的,使用live()会让你的生活变得更轻松。如果你不确切地知道你正在加载的代码但是你知道你将要听的是什么类型的元素,那么使用这个函数是完全合理的。
在性能提升方面,使用live()的一种替代方法是实现一个AJAX回调函数来重新绑定事件挂钩。
var ajaxCallback = function(){
$('*').unbind('click');
$('.something').bind('click', someFunction);
$('.somethingElse').bind('click', someOtherFunction);
}
您需要保持对事件挂钩的正确跟踪,并确保此功能重新绑定正确的事件。
P.S。 Ajax方法.get(),. post(),. load()和.ajax()都允许您指定回调函数。
答案 8 :(得分:0)
如果您需要简化代码,那么在大多数情况下,live会更好。 如果您需要获得最佳性能,那么委托将永远比生活更好。 bind(click)vs delegate不是那么简单的问题(如果你有很多类似的项目,那么委托会更好)。
答案 9 :(得分:0)
请记住,“live”的使用是针对“jQuery 1.3”或更高版本的
版本“jQuery 1.4.3”或更高版本使用“delegate”
和版本“jQuery 1.7 +”或更高版本用于“on”
$( selector ).live( events, data, handler ); // jQuery 1.3+
$( document ).delegate( selector, events, data, handler ); // jQuery 1.4.3+
$( document ).on( events, selector, data, handler ); // jQuery 1.7+
从jQuery 1.7开始,不推荐使用.live()方法。
此致 费尔南多
答案 10 :(得分:0)
除了T.J. Crowders answer之外,我还添加了一些处理程序 - 包括较新的.on(...)
处理程序,以便您可以看到哪些事件被隐藏,哪些事件不被隐藏。
我还发现.live()
不仅被弃用,而且自jQuery 1.9.x以来被删除。但其他的,即.click
,.delegate
/ .undelegate
和.on
/ .off
还在那里。
另请注意,有关此主题的更多讨论here on Stackoverflow。
如果您需要修复依赖.live的遗留代码,但需要使用新版本的jQuery(&gt; 1.8.3),则可以使用此代码段修复它:
// fix if legacy code uses .live, but you want to user newer jQuery library
if (!$.fn.live) {
// in this case .live does not exist, emulate .live by calling .on
$.fn.live = function(events, handler) {
$(this).on(events, null, {}, handler);
};
}
以下代码段的意图是TJ脚本的扩展,您可以自行尝试如果绑定多个处理程序会发生什么 - 所以请运行代码段并单击文本下面:
jQuery(function($) {
// .live connects function with all spans
$('span').live('click', function() {
display("<tt>live</tt> caught a click!");
});
// --- catcher1 events ---
// .click connects function with id='catcher1'
$('#catcher1').click(function() {
display("Click Catcher1 caught a click and prevented <tt>live</tt> from seeing it.");
return false;
});
// --- catcher2 events ---
// .click connects function with id='catcher2'
$('#catcher2').click(function() {
display("Click Catcher2 caught a click and prevented <tt>live</tt>, <tt>delegate</tt> and <tt>on</tt> from seeing it.");
return false;
});
// .delegate connects function with id='catcher2'
$(document).delegate('#catcher2', 'click', function() {
display("Delegate Catcher2 caught a click and prevented <tt>live</tt> from seeing it.");
return false;
});
// .on connects function with id='catcher2'
$(document).on('click', '#catcher2', {}, function() {
display("On Catcher2 caught a click and prevented <tt>live</tt> from seeing it.");
return false;
});
// --- catcher3 events ---
// .delegate connects function with id='catcher3'
$(document).delegate('#catcher3', 'click', function() {
display("Delegate Catcher3 caught a click and <tt>live</tt> and <tt>on</tt> can see it.");
return false;
});
// .on connects function with id='catcher3'
$(document).on('click', '#catcher3', {}, function() {
display("On Catcher3 caught a click and and <tt>live</tt> and <tt>delegate</tt> can see it.");
return false;
});
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
});
&#13;
<!-- with JQuery 1.8.3 it still works, but .live was removed since 1.9.0 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
</script>
<style>
span.frame {
line-height: 170%; border-style: groove;
}
</style>
<div>
<span class="frame">Click me</span>
<span class="frame">or me</span>
<span class="frame">or me</span>
<div>
<span class="frame">I'm two levels in</span>
<span class="frame">so am I</span>
</div>
<div id='catcher1'>
<span class="frame">#1 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
<span class="frame">me too</span>
</div>
<div id='catcher2'>
<span class="frame">#2 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
<span class="frame">me too</span>
</div>
<div id='catcher3'>
<span class="frame">#3 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
<span class="frame">me too</span>
</div>
</div>
&#13;