jQuery:如何监听 DOM 变化?

IT技术 javascript jquery html events
2021-02-22 01:36:31

是否有可能以及如何使用 jQuery 侦听整个 DOM 树中的更改?

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

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

4个回答

我最好的猜测是您想收听 DOM 突变事件。您可以通过 DOM 突变事件来做到这一点,就像任何普通的 javascript 事件(例如鼠标单击)一样。

参考这个:W3 MutationEvent

例子:

$("element-root").bind("DOMSubtreeModified", "CustomHandler");
改用 Mutation Observer
2021-04-15 01:36:31
处理程序上不需要引号,这是将函数绑定到事件的一种方法。
2021-04-18 01:36:31
突变事件已被弃用
2021-04-26 01:36:31
这段代码可能看起来短小精​​悍,但是当存在下面的事件委托解决方案时,它给浏览器带来的负载对于这个用例来说是微不足道的
2021-05-01 01:36:31
但是,DOMSubtreeModified 应该用引号括起来。
2021-05-14 01:36:31

[编辑回复成员托尼的研究]

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

关于#1: 当您将自定义事件绑定到元素时,您可以使用,event.preventDefault()以便不出现工具提示。这不能正常工作。因此,继续使用“title”属性的解决方法是获取值,将其推送到数据对象($.data()函数)中,然后将标题设为空字符串(removeAttr 不一致)。然后在鼠标离开时,您从数据对象中获取值并将其推回标题中。这个想法来自这里: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 更改重新绑定,委托的侦听器会自动处理它。并且您应该能够仅通过阻止它来阻止默认工具提示功能。

这里是最明智的方法!.... 然后在 mouseenter 中可以测试标题是否已移动到 $(this).data('title') 或没有
2021-04-25 01:36:31
@charlietfl 我一开始没明白你的意思,但现在我和你在一起!
2021-05-02 01:36:31
将是最优雅的解决方案,但似乎preventDefault不会阻止mouseover(至少在 Chrome 中)显示标题- code.google.com/p/chromium/issues/detail?id=42549
2021-05-06 01:36:31
@Greg 仍然需要一个小的调整,如果标题已经被删除,最终将在 data 中存储空字符串
2021-05-09 01:36:31
@Tony 好找;我认为它在 Fx 中也失败了。我已经更新了新代码。
2021-05-14 01:36:31

正如 Greg Pettit 所指出的,您应该在元素上使用 on() 函数。

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

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

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

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

希望这是有道理的:)

你有一个错字,应该.bind('mouseenter')不是.('mouseenter')
2021-04-24 01:36:31