我想知道是否有任何情况下最好使用.click(function {...});
而不是.live('click', function {...});
?
从我的理解来看,.live()
选项似乎是更好的选择,因此在几乎所有情况下,我都使用它而不是普通的.click()
,特别是考虑到我的许多代码是异步加载的。
编辑:
此问题的另一个部分是,如果我异步加载了所有javascript代码,那么.click()
仍将捕获dom中已经存在的所有元素。对吗?
我想知道是否有任何情况下最好使用.click(function {...});
而不是.live('click', function {...});
?
从我的理解来看,.live()
选项似乎是更好的选择,因此在几乎所有情况下,我都使用它而不是普通的.click()
,特别是考虑到我的许多代码是异步加载的。
编辑:
此问题的另一个部分是,如果我异步加载了所有javascript代码,那么.click()
仍将捕获dom中已经存在的所有元素。对吗?
有时候你可能只想显式地将点击处理程序分配给已经存在的对象,并以不同方式处理新对象。但更常见的情况是,live()
并不总是有效。它无法与像下面这样的链式 jQuery 语句一起使用:
$(this).children().live('click',doSomething);
由于事件冒泡的方式,它需要一个选择器才能正常工作。
编辑:有人刚刚点赞了这个问题,所以显然还有人在关注。我应该指出,live
和 bind
都已经被弃用。你可以使用.on()
来执行两者,这在我看来是一种更清晰的语法。要替换 bind
:
$(selector).on('click', function () {
...
});
并且替换 live
:
$(document).on('click', selector, function () {
...
});
你可以使用包含所需点击元素的任何 jQuery 对象来代替 $(document)
,但在调用它时,相应的元素必须存在。
(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>
在设置事件时,与 .click 相关联的所有对象必须存在。
例如(伪代码)可以使用 $("body").append()
进行附加操作。
append('<div id="foo" class="something">...</div>');
$("div.something").click(function(){...});
append('<div id="bar" class="something">...</div>');
点击可以运作于foo但无法运作于bar
例2:
append('<div id="foo" class="something">...</div>');
$("div.something").live("click",function(){...});
append('<div id="bar" class="something">...</div>');
点击事件对于 foo 和 bar 都起作用。
使用 .live('click'...,您可以在创建事件后动态添加更多的对象,并且点击事件仍将起作用。
"live"在动态生成代码时是必需的。 只需查看以下示例:
$("#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>
没有使用"live"时,点击事件仅在您单击第一个按钮时发生。使用"live"后,动态生成的按钮也可以触发点击事件。
如果您没有动态添加元素,请始终使用click
。
live
通过向文档根添加事件侦听器并侦听冒泡事件来工作。另一种选择是delegate
,它的工作方式相同,但将事件处理程序绑定到指定的元素。
这样,事件不必冒泡整个DOM并且可以更早地被捕获。
.live() 用于在初始页面加载后添加元素。假设您有一个按钮,在页面加载后通过 AJAX 调用添加。这个新按钮将无法使用 .click(),因此您必须使用 .live('click')。
var ajaxCallback = function(){
$('*').unbind('click');
$('.something').bind('click', someFunction);
$('.somethingElse').bind('click', someOtherFunction);
}
您需要正确跟踪您的事件钩子,并确保此函数重新绑定了正确的事件。
p.s. Ajax 方法 .get()、.post()、.load() 和 .ajax() 都允许您指定回调函数。
由于'live'会处理未来与当前选择器匹配的元素的事件,因此您可以选择单击(click),因为您不希望发生这种情况 - 您只想处理当前选择的元素。
另外,我怀疑(尽管没有证据)使用'click'比'live'效率略高。
李
除了T.J. Crowders answer,我还添加了一些处理程序-包括较新的.on(...)
处理程序到片段中,以便您可以看到哪些事件被隐藏,哪些事件没有被隐藏。
我发现.live()
不仅已经过时,而且自jQuery 1.9.x以来已被删除。但是其他的,即.click
,.delegate
/.undelegate
和.on
/.off
仍然存在。
还要注意,在Stackoverflow上有更多关于这个主题的讨论。
如果您需要修复依赖.live的旧代码,但又需要使用新版本的jQuery(>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);
};
}
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);
}
});
<!-- 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>
请记住,“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()方法已被弃用。
请查看http://api.jquery.com/live/
祝好, Fernando
.live
**方法已被删除。 - Matt