【问题标题】:$('.button').on("DOMSubtreeModified") does not work in chrome/safari, but works in Firefox$('.button').on("DOMSubtreeModified") 在 chrome/safari 中不起作用,但在 Firefox 中起作用
【发布时间】:2015-02-07 08:26:13
【问题描述】:

下面的代码不能在 Chrome/Safari 中运行但在 FireFox 中运行良好的原因是什么?

$(function() {
    $('.button').on("DOMSubtreeModified",function(){
        alert("button value changed");
    });
});

有没有其他方法可以让它在其他浏览器中发生?我正在尝试检测按钮值的变化。

与.button 绑定什么事件以动态更改按钮值?

【问题讨论】:

  • 我认为 Mouser 和 user625488 误读了这个问题。他们告诉你如何获得DOMSubtreeModified 事件的功能,而不是change 事件。
  • 问题中的代码示例具体使用了DOMSubtreeModified。您还可以使用突变观察者专门观察value 属性的变化。我不明白提到突变观察者的两个答案是如何错过重点的。

标签: javascript jquery google-chrome firefox


【解决方案1】:

在我看来,onchange 只会在输入更改时触发输入元素。由于您指的是按钮,因此输入不会改变,change 事件不会触发。因此,您需要一个监控元素更改的解决方案:

对于现代浏览器,我建议变异观察者

        var observer = new MutationObserver( [observer function] );
        // configuration of the observer:
        var config = { attributes: false, childList: true, characterData: true, subtree: true };

        // pass in the target node, as well as the observer options
        observer.observe(element, config);

这会为您的元素添加一个突变观察者。您可以配置观察者需要监听的选项。 Jquery 本身不支持此功能(目前)。

  • childList 如果要观察目标节点的子元素(包括文本节点)的添加和删除,则设置为 true。 attributes 如果要观察到目标属性的突变,则设置为 true。
  • characterData 如果要观察目标数据的突变,则设置为 true。
  • subtree 如果不仅要观察目标的突变,还要观察目标的后代的突变,则设置为 true。
  • attributeOldValue 如果 attributes 设置为 true,并且需要记录突变之前的目标属性值,则设置为 true。
  • characterDataOldValue 如果 characterData 设置为 true 并且需要记录突变之前的目标数据,则设置为 true。
  • attributeFilter 如果不需要观察所有属性突变,则设置为属性本地名称数组(无命名空间)。

来源:MDN

哪些浏览器支持此功能:CanIuse
在此处阅读更多信息:MDN

对于您的项目:

$(".button").each(function(){
    this.observer = new MutationObserver( observeButtonChange);
    // configuration of the observer:
    //you can play with these.
    var config = { attributes: false, childList: true, characterData: true, subtree: false};

    // pass in the target node, as well as the observer options
    this.observer.observe(this, config); //starts the actual observing of the element.

});

function observeButtonChange(mutations)
{
    alert("Button has changed");
}

这段代码搜索页面上所有类名为.button 的元素,并使用jQuery 的each 为其附加一个Mutation Observer。每次buttonDOM 树 发生变化都会触发observeButtonChange 函数。事件对象mutations 包含很多关于触发事件的信息,包括添加和删除的元素。它是一个包含有关各种侦听器的数据的数组。我建议听一下characterDatachildList 选项,因为它们表示按钮的值发生了变化。

【讨论】:

  • 不加评论就投反对票,太好了。
  • 很好的答案,我的 DOMSubtreeModified 处于循环状态(仅在 IE 和 Firefox 中),因为我在修改 dom 后对其进行了编辑 - 动态添加内容,并在更新时使用 javascript 进行整理。这至少解决了我的问题
【解决方案2】:

新答案

第二次尝试!我要做的是结合使用 jQuery ON 和 TRIGGER。

创建一个自定义事件监听器,如下所示:

$( ".button" ).on( "dynValueChange", function() {
    alert("button value changed");
});

然后,将以下触发器添加到动态更改按钮值的函数中。

$(".button").trigger("dynValueChange");

这可能不像使用 DOMSubtreeModified 那样干净或简单,但我可以保证它适用于所有浏览器。

如果需要更好的解释,请告诉我。

原始答案

尝试使用下面的代码。这利用 jQueries 更改功能在“.button”元素上应用事件处理程序。这仅在元素“.button”上的 value 属性发生变化时才有效。

$(function() {
    $('.button').change(function(){
        alert("button value changed");
    });
});

祝你好运! http://api.jquery.com/change/

亚当

【讨论】:

  • 它不起作用。我的按钮值动态变化。
  • 我很抱歉。我没有考虑 DOM 修改。我有一个解决方案,但它没有应用 DOM 修改事件侦听器。
【解决方案3】:

The section about legacy events in the DOM level 3 spec 应该给你一个答案,为什么这个事件没有在所有浏览器中实现,为什么它工作不一致,为什么随着时间的推移它会在更少的浏览器中可用,以及为什么使用它通常是个坏主意。 TL;博士;它很慢,因此已被弃用,并且随着新浏览器版本的发布,对它的支持也将被删除。

同时the section about mutation observers in the newest DOM spec提供了替代品。

Mozilla 开发者网络提供了一个不那么枯燥的 more hands-on usable description of mutation observers。 jQuery 不提供使用突变观察者的内置快捷方式,因此您必须手动将观察者附加到 DOM - 但您可以使用 jQuery 完成所有其他操作。

可以像这样附加一个变异观察者:

var target = $(".button" )[0];
var observer = new MutationObserver(function(mutations) {
    // body of your handler comes here - you can use jQuery in here
    // typically, you iterate over mutations here, and handle
    // each according to its type
});
// additional members for configuration documented in the spec
// attributes: true says the observer should receive a mutation
// when an attribute of the watched target changes
var observerConfig = { attributes: true }; 
observer.observe(target, observerConfig);

稍后,当您完成对突变的观察后,您应该销毁您的突变观察器,以使浏览器的垃圾收集变得容易:

observer.disconnect();

您传递给突变观察者的函数接收到的mutations 参数是MutationRecord 的数组 - 在the spec 中也有描述。该接口有各种成员用于查询其类型(属性更改、文本更改、添加或删除子项等),以及更改的内容 - 更改后的属性的名称及其更改前的值,用于attributes 类型的突变。

请注意,上面的代码示例仅附加到 DOM 中类 button 的第一个元素。您需要为每个目标调用observer.observe(),以将其附加到所有具有button 类的元素:

$('.button').each(function(index, element) {
    observer.observe(element, config);
});

根据the spec,您可以使用一个观察者来观察多个元素的突变,因此您无需为每个.button 创建一个新的。

我认为这不会像 DOM 突变事件那样方便。但是你想要的仍然是可行的。

【讨论】:

  • 单独的突变观察器只允许断开特定元素的连接。在您的代码中调用 disconnect 将停止侦听所有附加元素。
  • @Mouser 你说得对。但这也是问题中的代码示例也试图完成的任务 - 将相同的处理程序附加到所有 .button 元素。在事实上的标准 jQuery 习惯用法中,您稍后会调用 $(".button").off("dynValueChange") 来删除事件处理程序。
猜你喜欢
  • 2011-12-11
  • 1970-01-01
  • 1970-01-01
  • 2012-10-24
  • 2011-05-03
  • 1970-01-01
  • 2018-04-20
  • 2014-04-03
  • 2015-07-29
相关资源
最近更新 更多