Bei der Arbeit mit VueJS in Kombination mit jQuery kommt es häufig zu dem Problem, dass VueJS das DOM oder sogar das data-Attribut eines Elementes ändert, aber jQuery noch per jQuery.data() auf alte Daten zugreift.
Hintergrund: Beim Initialisieren der Elemente cached jQuery die data-*-Attribute und speichert sie in einer internen Variable, um später schneller darauf zugreifen zu können. Eine Änderung der data-*-Attribute über VueJS – oder bereits eine Änderung der Reihenfolge der Elemente im DOM – führt zu einer falschen Zuordnung zwischen Element und dem data-Cache von jQuery.
Dieses kleine Plugin löst das Problem: Nach einer Änderung des DOM über VueJS kann einfach $('.element').rebuildData();
aufgerufen werden, um alle data-Attribute des Elementes und rekursiv aller Unterknoten erneut zu parsen und in jQuery.data() zu speichern.
Für Suchmaschinen: rebuild data-attribute with jQuery, delete data-Cache jQuery, refresh and reload data-attribute in jQuery. Clear data-cache and reinitialize data-attributes in jQuery. Problem VueJS data-attribute parsing with jQuery. Force reparsing the data-attributes in jQuery when DOM is dynamically changed. Disable the data-Cache in jQuery.
(function () {
$.fn.extend({
/**
* jQuery.data() liefert ein falsches Ergebnis in Verbindung mit VueJS:
* Werden Elemente dynamisch im DOM verändert, referenziert der jQuery.data()-Cache
* evtl. auf Elemente, die ersetzt wurden.
*
* Wurde ein [data-]-Attribut einmal über jQuery.fn.data() eingelesen,
* liefert jQuery immer den gecachten Wert – auch wenn sich das Tag-Attribut
* verändert hat, z.B. data-poi-uid="10" in data-poi-uid="33" geändert wurde.
*/
'rebuildData': function () {
return this.each(function () {
$(this).add($(this).find('*')).each(function () {
var i, name, data, elem = this,
attrs = elem && elem.attributes;
if (elem.nodeType === 1) {
i = attrs.length;
var obj = {};
while (i--) {
if (attrs[i]) {
name = attrs[i].name;
if (name.indexOf("data-") === 0) {
name = jQuery.camelCase(name.slice(5));
var val = attrs[i].value;
if ($.isNumeric(val)) val *= 1;
obj[name] = val;
}
}
}
$(this).data(obj);
}
});
});
}
});
})(jQuery);