在jQuery中,如何将事件附加到dynamichtml元素?
假设我有一些jQuery代码将一个事件处理程序附加到类“myclass”的所有元素上。 例如:
$(function(){ $(".myclass").click( function() { // do something }); });
而我的html可能如下所示:
<a class="myclass" href="#">test1</a> <a class="myclass" href="#">test2</a> <a class="myclass" href="#">test3</a>
这没有问题。 但是,请考虑是否将“myclass”元素在未来某个时间写入页面。
例如:
<a id="anchor1" href="#">create link dynamically</a> <script type="text/javascript"> $(function(){ $("#anchor1").click( function() { $("#anchor1").append('<a class="myclass" href="#">test4</a>'); }); }); </script>
在这种情况下,当用户点击#anchor1时会创build“test4”链接。
“test4”链接没有与之关联的click()处理程序,尽pipe它具有class =“myclass”。
任何想法如何我可以解决这个问题?
基本上,我想编写一次click()处理程序,并将其应用于页面加载时的内容和稍后通过Ajax / DHTML引入的内容。
我添加了一个新的答案,以反映后来的jQuery版本的变化。 .live()方法从jQuery 1.7开始被弃用。
从jQuery 1.7开始,.live()方法已被弃用。 使用.on()附加事件处理程序。 老版本的jQuery用户应该优先使用.delegate().live()。
对于jQuery 1.7以上版本,您可以使用.on()将事件处理程序附加到父元素,并将与“myclass”组合的select器作为parameter passing。
所以,而不是…
$(".myclass").click( function() { // do something });
你可以写…
$('body').on('click', 'a.myclass', function() { // do something });
这将适用于所有在主体中具有'myclass'的标签,不pipe是否已经存在或稍后dynamic添加。
这里使用的是body标签,因为这个例子中没有更接近静态的标签,但是当发生.on方法调用时,任何父标签都可以使用。 例如,添加dynamic元素的列表的ul标签将如下所示:
$('ul').on('click', 'li', function() { alert( $(this).text() ); });
只要ul标签存在,这将工作(没有李元素需要存在呢)。
有时候做这个(顶级答案)并不总是足够的:
$('body').on('click', 'a.myclass', function() { // do something });
这可能是一个问题,因为命令事件处理程序被触发。 如果你发现自己这样做了,但是由于它的处理顺序而引起问题。你总是可以把它包装到一个函数中,当被调用时“刷新”监听器。
例如:
function RefreshSomeEventListener() { // Remove handler from existing elements $("#wrapper .specific-selector").off(); // Re-add event handler for all matching elements $("#wrapper .specific-selector").on("click", function() { // Handle event. } }
因为这是一个函数,所以每当我这样设置我的监听器的时候,我通常会在文档上调用它:
$(document).ready(function() { // Other ready commands / code // Call our function to setup initial listening RefreshSomeEventListener(); });
然后,每当添加一些dynamic添加的元素时,再次调用该方法:
function SomeMethodThatAddsElement() { // Some code / AJAX / whatever.. Adding element dynamically // Refresh our listener, so the new element is taken into account RefreshSomeEventListener(); }
希望这有助于!
问候,
在jQuery 1.7之后,首选的方法是.on()和.off ()
肖恩的回答显示了一个例子。
现已过时:
使用jQuery函数
.live()
和.die()
。 在jQuery 1.3.x中可用从文档:
每当单击一个警报框时,都会显示每个段落的文本:
$("p").live("click", function(){ alert( $(this).text() ); });
而且,这个livequery插件可以做到这一点,并支持更多的事件。
将处理程序绑定到所有当前和将来匹配的元素的事件(如单击)。 也可以绑定自定义事件。
链接文本
$(function(){ $(".myclass").live("click", function() { // do something }); });
如果你正在向DOM添加一堆锚点,请考虑事件委托。
这是一个简单的例子:
$('#somecontainer').click(function(e) { var $target = $(e.target); if ($target.hasClass("myclass")) { // do something } });
如果你在jQuery 1.3+然后使用。 生活()
将处理程序绑定到所有当前和将来匹配的元素的事件(如单击)。 也可以绑定自定义事件。
你想使用live()
函数。 看文档 。
例如:
$("#anchor1").live("click", function() { $("#anchor1").append('<a class="myclass" href="#">test4</a>'); });
您可以将一个单击事件绑定到所有元素的页面,而不pipe它们是否已经在该页面上,或者是否将在未来某个时间到达,如下所示:
$(document).bind('click', function (e) { var target = $(e.target); if (target.is('.myclass')) { e.preventDefault(); // if you want to cancel the event flow // do something } else if (target.is('.myotherclass')) { e.preventDefault(); // do something else } });
已经使用了一段时间。 奇迹般有效。
在jQuery 1.7和更高版本中,build议使用.on()
代替绑定或任何其他事件委托方法,但.bind()
仍然有效。