DOM 属性更改时触发事件

IT技术 javascript jquery dom events dom-events
2021-02-01 21:47:53

有没有办法在属性更改时触发事件(可能是自定义的)?

假设,当 IMG src 更改或 DIV 的 innerHtml 更改时?

6个回答

注意:截至 2012 年,Mutation Events 已从标准中删除,现已弃用。请参阅其他答案或文档以了解如何使用它们的替代品MutationObserver

您指的是DOM Mutation Events浏览器对这些事件的支持很差(但正在改进)。jQuery 的 Mutation Events 插件可能会给你一些帮助。

@TimDown 如果涉及到 IE,这并不奇怪。
2021-03-13 21:47:53
对我来说,这个答案太简洁了。我不知道如何使用 jquery 插件。但是 Mats 的答案很简单,不需要额外的插件。
2021-03-20 21:47:53
DOM 突变事件实际上在浏览器中得到了相当好的支持。只是 IE 根本不支持它们(尽管 IE 9 会)。
2021-03-28 21:47:53
现在,这些均弃用,取而代之的MutationObserverdeveloper.mozilla.org/en-US/docs/Web/API/MutationObserver
2021-04-08 21:47:53

如何设置 MutationObserver,主要是从MDN复制的,但为了清楚起见,我添加了自己的评论。

window.MutationObserver = window.MutationObserver
    || window.WebKitMutationObserver
    || window.MozMutationObserver;
// Find the element that you want to "watch"
var target = document.querySelector('img'),
// create an observer instance
observer = new MutationObserver(function(mutation) {
     /** this is the callback where you
         do what you need to do.
         The argument is an array of MutationRecords where the affected attribute is
         named "attributeName". There is a few other properties in a record
         but I'll let you work it out yourself.
      **/
}),
// configuration of the observer:
config = {
    attributes: true // this is to watch for attribute changes.
};
// pass in the element you wanna watch as well as the options
observer.observe(target, config);
// later, you can stop observing
// observer.disconnect();

希望这可以帮助。

在 Chrome 中就像一个魅力。真的好用!
2021-03-21 21:47:53

如果您只需要特定的东西,那么一个简单的方法setInterval()就可以工作,通过每隔几毫秒检查一次目标属性:

var imgSrc = null;
setInterval(function () {
   var newImgSrc = $("#myImg").attr("src");
   if (newImgSrc !== imgSrc) {
      imgSrc = newImgSrc;
      $("#myImg").trigger("srcChange");
   }
}, 50);

然后绑定到自定义的“srcChange”事件:

$("#myImg").bind("srcChange", function () {....});
在我看来,为此使用间隔真的很差(是的,这是“一种”方式)。
2021-03-27 21:47:53
MutationObserver 可能是一个更优雅的解决方案,但是如果所讨论的元素还没有生成呢?而出于调试目的,我认为让事情暂时有点混乱是可以的。我目前的用例是试图找出导致错误更改 Legacy 系统中值的原因,因此该解决方案实际上比更清洁的解决方案更适合我。
2021-03-29 21:47:53
间隔的使用在数量有限的情况下是合适的,尤其是在性能不会成为问题的情况下。我没有运行任何基准测试,但我从经验中知道我可以在一个快速的时间间隔内操作 DOM 中的所有类型的属性而不会注意到性能下降。
2021-04-04 21:47:53

没有您可以挂钩的本地 dom 更改事件。

这里的好文章试图以 jquery 插件的形式提供解决方案。

文章中的代码

$.fn.watch = function(props, callback, timeout){
    if(!timeout)
        timeout = 10;
    return this.each(function(){
        var el      = $(this),
            func    = function(){ __check.call(this, el) },
            data    = { props:  props.split(","),
                        func:   callback,
                        vals:   [] };
        $.each(data.props, function(i) {
              data.vals[i] = el.css(data.props[i]); 
        });
        el.data(data);
        if (typeof (this.onpropertychange) == "object"){
            el.bind("propertychange", callback);
        } else if ($.browser.mozilla){
            el.bind("DOMAttrModified", callback);
        } else {
            setInterval(func, timeout);
        }
    });
    function __check(el) {
        var data    = el.data(),
            changed = false,
            temp    = "";
        for(var i=0;i < data.props.length; i++) {
            temp = el.css(data.props[i]);
            if(data.vals[i] != temp){
                data.vals[i] = temp;
                changed = true;
                break;
            }
        }
        if(changed && data.func) {
            data.func.call(el, data);
        }
    } }
“好文章”链接坏了:(
2021-03-23 21:47:53
这种方法有相当大的性能影响。
2021-04-08 21:47:53

除了MDN 的 MutationObserver 示例用法启发的Mats 回答

如果您的选项包含<property>: true并且您计划回调函数中更改target 的此属性MutationObserver,请使用以下内容来防止递归调用 - 直到脚本超时、堆栈溢出等:

...
// Used to prevent recursive calls of observer's callback function
// From https://stackoverflow.com/questions/4561845/firing-event-on-dom-attribute-change
let insideInitialObserverCallback = false

let callback = function(mutationsList) {
    insideInitialObserverCallback = ! insideInitialObserverCallback
    if ( insideInitialObserverCallback ) {

        // ... change target's given property ...       

    }
})

let observer = new MutationObserver(callback);
...