jQuery:如何监听DOM更改?

时间:2012-02-28 19:48:09

标签: javascript jquery html events

是否可以,如何通过jQuery监听整个DOM树的更改?

我的具体问题:我有一个'工具提示'功能,当您对任何html元素执行title时,它会以时尚的方式显示hover属性的内容。但是,当您进行悬停时,标准浏览器会在自己的框中呈现title。我想压制它。所以我想到的是在第一次加载页面时将title属性的内容移动到自定义(HTML5)data-title属性,然后我的工具提示函数将与{{ 1}}。

问题是,稍后我可能会动态添加/删除/更改HTML,因此我需要'重新绑定'这些元素 - 再次更改这些标题。如果有一个事件监听器会为我监听这些更改并自动重新绑定元素,那就太好了。

4 个答案:

答案 0 :(得分:35)

我最好的猜测是你想听DOM变异事件。 你可以通过DOM突变事件做任何正常的javascript事件,如鼠标点击。

请参阅:W3 MutationEvent

示例:

$("element-root").bind("DOMSubtreeModified", "CustomHandler");

答案 1 :(得分:2)

[回复成员Tony的研究报告]

所以,如果没有额外的代码,这是一个盲目的镜头,但在我看来这里有两件事要考虑:1。默认的浏览器工具提示行为; 2.可能更新的DOM以及自定义工具提示继续运行的功能。

关于#1:将自定义事件绑定到元素时,可以使用event.preventDefault()以便不显示工具提示。这不能正常工作。因此,继续使用“title”属性的解决方法是获取值,将其推入数据对象($.data()函数),然后使用空字符串清空标题(removeAttr不一致)。然后在mouseleave上,从数据对象中获取值并将其推回到标题中。这个想法来自这里:How to disable tooltip in the browser with jQuery?

关于#2:您只需要将一次绑定到一个永远不会被销毁的侦听器元素,而不是重新绑定DOM更改。通常这是某种容器元素,但如果你真的需要一个包罗万象的容器,它甚至可以是document(近似.live()现已弃用)。这是一个使用我自己设计的假标记的示例:

var container = $('.section');

container.on('mouseenter', 'a', function() {
    var $this = $(this);
    var theTitle = $this.attr('title');
    $this.attr('title', '');
    $('#notatooltip').html(theTitle);   
    $.data(this, 'title', theTitle);
});

container.on('mouseleave', 'a', function() {
    $('#notatooltip').html('');
    var $this = $(this);
    var storedTitle = $.data(this, 'title');
    $this.attr('title', storedTitle);
});

我的不切实际的标记(仅针对此示例)位于:

<div class="section">
  <a href="#" title="foo">Hover this foo!</a>
  <div id="notatooltip"></div>
</div>

这里有一个小提琴:http://jsfiddle.net/GVDqn/ 或者进行一些健全性检查:http://jsfiddle.net/GVDqn/1/

可能有一种更优化的方法(我老实说没有研究是否可以使用一个选择器将两个单独的事件绑定两个单独的函数),但它会做到这一点。

您不需要根据DOM更改重新绑定,委派的侦听器将自动处理它。而且你应该能够通过防止它来阻止默认的工具提示功能。

答案 2 :(得分:0)

答案 3 :(得分:0)

正如Greg Pettit所说,你应该在元素上使用on()函数。

这样做是允许您将选择器绑定到事件,然后当选择器返回的对象可用时,jQuery将添加此事件处理程序。

如果你想要一个鼠标悬停在一个事件上的函数,并且你希望它在 * field_title * 类的所有元素上触发,你可以这样做:

$('.field_title').bind('mouseenter', function() { doSomething(); });

这将触发任何具有 * field_title * 类的对象上的鼠标悬停事件,并执行 doSomething()

希望有道理:)