jQuery rebuild data – data-Attribut erneut parsen / einlesen

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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.