domsubtreemodified - mutationobserver example
¿Existe alguna alternativa a DOMAttrModified que funcione en webkit? (5)
Consulte el código: https://github.com/meetselva/attrchange/blob/master/attrchange.js ''DOMAttrModified'' + (''propertychange'' para IE) se utilizan allí como en su caso. Si no es adecuado para usted, la solución "fea" que puede satisfacer esta demanda debe establecerse Intervalo (función () {}, demora) De lo contrario, consulte la publicación anterior de Sean Hogan.
Necesito aprovechar este evento DOM. IE tiene onpropertychange, que hace lo que necesito que haga también. Webkit no parece apoyar este evento, sin embargo. ¿Hay alguna alternativa que pueda usar?
La solución proporcionada por @Filip está cerca (y puede haber funcionado en ese momento) pero ahora debe solicitar la entrega del valor del atributo anterior.
Por lo tanto, querrás cambiar:
observer.observe(element, { attributes: true, subtree: bubbles });
a esto:
observer.observe(element, { attributes: true, attributeOldvalue:true, subtree: bubbles });
De lo contrario, no verás los antiguos valores (en su lugar obtendrás un valor nulo). Esto se probó en Chrome 34.0.1847.131 (compilación oficial 265687) m.
Si está contento simplemente con detectar llamadas a setAttribute()
(en lugar de monitorear todas las modificaciones de atributos), puede anular ese método en todos los elementos con:
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);
}
Tenía la misma pregunta y estaba pensando en modificar setAttribute
, así que al ver lo que hizo Sean , lo copié. Funcionó muy bien, excepto que estaba disparando cuando un atributo se estableció repetidamente en el mismo valor, por lo que agregué un cheque a mi copia para omitir la activación del evento si el valor no se cambia. También agregué val = String(val)
, en base al razonamiento de que setAttribute
los números a las cadenas, por lo que la comparación debe anticipar eso.
Mi versión modificada es:
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();
Aunque Chrome no distribuye eventos DOMAttrModified
, los observadores de mutaciones más DOMAttrModified
son compatibles desde 2011 y también funcionan para cambios de atributos.
Aquí hay un ejemplo para el cuerpo del 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 un simple cambio de atributo, la instrucción console.log
se imprimiría:
<body color="black">
<script type="text/html">
document.body.setAttribute("color", "red");
</script>
</body>
Consola:
> color red black