【问题标题】:jQuery: How to listen for DOM changes?jQuery:如何监听 DOM 变化?
【发布时间】:2012-02-28 19:48:09
【问题描述】:

是否有可能以及如何使用 jQuery 监听整个 DOM 树的变化?

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

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

【问题讨论】:

标签: javascript jquery html events


【解决方案1】:

我最好的猜测是你想监听 DOM 突变事件。 您可以通过 DOM 突变事件来实现这一点,就像任何普通的 javascript 事件一样,例如鼠标点击。

参考这个:W3 MutationEvent

例子:

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

【讨论】:

  • 处理程序上不需要引号,这是将函数绑定到事件的一种方法。
  • 这段代码可能看起来很简短,但是当存在以下事件委托解决方案时,它给浏览器带来的负载对于这个用例来说是无用的
  • DOMSubtreeModified 应该用引号括起来。
  • 突变事件已经deprecated。
  • 改用 Mutation Observer
【解决方案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 更改重新绑定,委托的侦听器会自动处理它。您应该能够通过阻止默认工具提示功能来阻止它。

【讨论】:

  • 这里最明智的做法!.... 然后在 mouseenter 中可以测试标题是否已移动到 $(this).data('title') 或没有
  • 本来是最优雅的解决方案,但似乎 preventDefault 不会阻止在 mouseover 上显示标题(至少在 Chrome 中)-code.google.com/p/chromium/issues/detail?id=42549
  • @Tony 很好的发现;我认为它在 Fx 中也失败了。我已经更新了新代码。
  • @charlietfl 一开始我没听懂你的意思,但现在我和你在一起!
  • @Greg 仍然需要稍作调整,如果标题已被删除,最终将在 data 中存储空字符串
【解决方案3】:
【解决方案4】:

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

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

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

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

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

希望这是有道理的:)

【讨论】:

  • 你打错了,应该是.bind('mouseenter')而不是.('mouseenter')。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-13
  • 1970-01-01
相关资源
最近更新 更多