在webkit中是否有可以使用的DOMAttrModified替代方案

在webkit中是否有可以使用的DOMAttrModified替代方案,dom,webkit,mutation-events,Dom,Webkit,Mutation Events,我需要利用这个DOM事件。IE有onpropertychange,它也做了我需要它做的事情。然而,Webkit似乎不支持此事件。我可以使用其他方法吗?如果您只喜欢检测对setAttribute()的调用(而不是监视所有属性修改),那么您可以在所有元素上使用以下方法: Element.prototype._setAttribute = Element.prototype.setAttribute Element.prototype.setAttribute = function(name, val

我需要利用这个DOM事件。IE有onpropertychange,它也做了我需要它做的事情。然而,Webkit似乎不支持此事件。我可以使用其他方法吗?

如果您只喜欢检测对
setAttribute()
的调用(而不是监视所有属性修改),那么您可以在所有元素上使用以下方法:

Element.prototype._setAttribute = Element.prototype.setAttribute
Element.prototype.setAttribute = function(name, val) { 
 var e = document.createEvent("MutationEvents"); 
 var prev = this.getAttribute(name); 
 this._setAttribute(name, val);
 e.initMutationEvent("DOMAttrModified", true, true, null, prev, val, name, 2);
 this.dispatchEvent(e);
}

尽管Chrome不发送
DOMAttrModified
事件,但自2011年以来,它支持更轻的变异观察者,这些观察者也适用于属性更改

以下是文档正文的示例:

var element = document.body, bubbles = false;

var observer = new WebKitMutationObserver(function (mutations) {
  mutations.forEach(attrModified);
});
observer.observe(element, { attributes: true, subtree: bubbles });

function attrModified(mutation) {
  var name = mutation.attributeName,
    newValue = mutation.target.getAttribute(name),
    oldValue = mutation.oldValue;

  console.log(name, newValue, oldValue);
}
对于简单的属性更改,
console.log
语句将打印:

<body color="black">
<script type="text/html">
document.body.setAttribute("color", "red");
</script>
</body>

document.body.setAttribute(“颜色”、“红色”);
控制台:

>红色-黑色

请参考代码: “DOMAttrModified”+(IE的“propertychange”)在那里的使用方式与您的情况类似。如果不适合您,可以满足此需求的“丑陋”解决方案应该是setInterval(function(){},delay)
否则,请参阅上面的Sean Hogan帖子。

由@Filip提供的解决方案已经接近成功(当时可能已经成功),但现在您需要请求传递旧的属性值

因此,您需要更改:

observer.observe(element, { attributes: true, subtree: bubbles });
为此:

observer.observe(element, { attributes: true, attributeOldvalue:true, subtree: bubbles });

否则,您将看不到旧值(改为null)。这是在Chrome 34.0.1847.131(官方版本265687)m中测试的。

我有同样的问题,正在考虑修改
setAttribute
,因此,我复制了它。它工作得很好,只是在属性被重复设置为相同值时触发,所以我在副本中添加了一个检查,以在值未更改时跳过触发事件。我还添加了
val=String(val)
,这是基于
setAttribute
将数字强制为字符串的原理,因此比较应该可以预料到这一点

我的修改版本是:

var emulateDOMAttrModified = {

  isSupportedNatively: function () {
    var supported = false;
    function handler() {
      supported = true;
    }
    document.addEventListener('DOMAttrModified', handler);
    var attr = 'emulateDOMAttrModifiedTEST';
    document.body.setAttribute(attr, 'foo'); // aka $('body').attr(attr, 'foo');
    document.removeEventListener('DOMAttrModified', handler);
    document.body.removeAttribute(attr);
    return supported;
  },

  install: function () {
    if (!this.isSupportedNatively() &&
      !Element.prototype._setAttribute_before_emulateDOMAttrModified) {
      Element.prototype._setAttribute_before_emulateDOMAttrModified = Element.prototype.setAttribute
      Element.prototype.setAttribute = function(name, val) {
        var prev = this.getAttribute(name);
        val = String(val); /* since attributes do type coercion to strings,
           do type coercion here too; in particular, D3 animations set x and y to a number. */
        if (prev !== val) {
          this._setAttribute_before_emulateDOMAttrModified(name, val);
          var e = document.createEvent('MutationEvents');
          e.initMutationEvent('DOMAttrModified', true, true, null, prev, val, name, 2);
          this.dispatchEvent(e);
        }
      };
    }
  }

};

// Install this when loaded.  No other file needs to reference this; it will just make Chrome and Safari
// support the standard same as Firefox does.
emulateDOMAttrModified.install();

这似乎目前无法与CSS3的“resize:tware”属性结合使用。观察者将不会通过用户拖动调整大小手柄来拾取对元素的更改。是否有任何方法可以查看更改的来源?我有一个元素,它的类通过JS在某处发生了更改,我试图找出它的来源,但是Chrome的事件堆栈跟踪没有显示启动事件的代码。值得注意的是,
domatrtModified
在属性更改时会立即触发,但变异观测者会将事件排队。因此,两者之间的区别并不那么细微。我相信
Webkit
前缀不再是必要的。基于这个,我已经创建了一个小的库来捕获DOM插入。如果您可以在您感兴趣的更改之后编写一个与元素匹配的CSS选择器,那么这是一个有效的解决方案。它覆盖的浏览器比DOM多。见: