existe uma alternativa ao DOMAttrModified que funcionará no webkit

Eu preciso aproveitar esse evento DOM. O IE tem onpropertychange, que faz o que eu preciso fazer também. O Webkit não parece suportar este evento, no entanto. Existe uma alternativa que eu poderia usar?

Embora o Chrome não DOMAttrModified events DOMAttrModified , os observadores de mutação mais leves são suportados desde 2011 e também funcionam para alterações de atributos.

Aqui está um exemplo para o corpo do documento:

 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); } 

Para uma alteração de atributo simples, a instrução console.log imprimir:

    

Console:

> color red black

Se você está satisfeito apenas com a detecção de chamadas para setAttribute() (em vez de monitorar todas as modificações de atributos), então você pode setAttribute() esse método em todos os elementos com:

 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); } 

Eu tive a mesma pergunta e estava pensando em modificar setAttribute , então, vendo o que Sean fez , eu copiei isso. Funcionou muito bem, exceto pelo fato de estar acionando quando um atributo foi repetidamente configurado para o mesmo valor, então eu adicionei um cheque à minha cópia para pular o evento se o valor não estivesse sendo alterado. Eu também adicionei val = String(val) , com base na lógica que setAttribute irá forçar números para seqüências de caracteres, portanto, a comparação deve antecipar isso.

Minha versão modificada é:

 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(); 

Por favor, consulte o código: https://github.com/meetselva/attrchange/blob/master/attrchange.js ‘DOMAttrModified’ + (‘propertychange’ para o IE) são utilizados como no seu caso. Se não for adequado para você, a solução “feia” que pode satisfazer essa demanda deve ser setInterval (function () {}, delay) Caso contrário, veja o post acima.

A solução fornecida pelo @Filip está próxima (e pode ter funcionado no momento), mas agora você precisa solicitar a entrega do antigo valor do atributo.

Assim, você vai querer mudar:

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

para isso:

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

Caso contrário, você não verá os oldValues ​​(em vez disso, você obterá null). Isso foi testado no Chrome 34.0.1847.131 (Official Build 265687) m.