2011-09-18 13 views
5

Dato questo CSS:browser non osservare modifiche al data-*, attributi CSS Proprietà del selettore non di rendering

[data-myplugin-object="blue-window"]{ 
    background-color: #00f; 
} 

[data-myplugin-object="red-window"]{ 
    background-color: #f00; 
} 

E questo jQuery:

$('[data-myplugin-object="blue-window"]').each(function(event){ 
    $(this).data({ 
     'myplugin-object': 'red-window' 
    }); 
}); 

E questo frammento di codice HTML:

<div data-myplugin-object="blue-window"> 
    <p>Hello world</p> 
</div> 

Ora, ci si aspetterebbe che quando il frammento jQuery viene eseguito (correttamente differito fino al il caricamento della pagina è completo ovviamente) la mia finestra blu (che inizialmente viene visualizzata come blu) diventa rossa.

No, certamente no; e usando Firebug e Developer Tools rispettivamente in Firefox e Chrome, non posso osservare alcuna modifica agli attributi data-*.

Affinché il browser (e toolbox DOM è per questo) per osservare i cambiamenti, ho bisogno per tornare a .attr() o c'è una soluzione per questo?

risposta

11

Gli attributi jQuery.data() non vengono effettivamente memorizzati nell'oggetto DOM in jQuery. L'oggetto DOM viene contrassegnato con un ID jQuery univoco e i dati effettivi vengono archiviati in una struttura dati javascript separata. Tra le altre ragioni, jQuery fa in questo modo per evitare bug di perdita di memoria di riferimento circolare che possono verificarsi in alcuni browser quando i valori dei dati sono riferimenti ad altri oggetti DOM.

Se si desidera modificare l'attributo reale DOM, io suggerirei di impostare l'attributo direttamente da soli in questo modo:

obj.attr("data-myplugin-object", "red-window"); 

Anche se, per quello che stai facendo, penso che la maggior parte delle persone sarebbe utilizzare l'aggiunta/rimuovendo/modificando i nomi delle classi CSS, non gli attributi personalizzati in quanto è il modo comune di cambiare quali regole CSS si applicano a un oggetto.

<div id="myObj" class="blueWindow"> 
    <p>Hello world</p> 
</div> 

.blueWindow {background-color: #00F;} 
.redWindow {background-color: #F00;} 

$("#myObj").removeClass("blueWindow").addClass("redWindow"); 

O se non ci sono altre classi sull'oggetto:

$("#myObj").attr("class", "redWindow"); 
+1

Grazie @ jfriend00 - classi CSS sono ovviamente più adatta per il caso di styling esclusivamente gli elementi, ma sto lavorando su un plugin e voleva implementare alcuni stili predefiniti basati sulla pertinenza semantica degli attributi personalizzati (* pertinenza al layout *) Questi naturalmente sono destinati a essere sostituiti con selettori CSS di specificità più elevata (* come '.classes' *) In qualsiasi caso, se il metodo '.attr()' è la mia migliore scommessa, allora questa è la direzione che andrò. '.data()' fornisce qualsiasi altra funzionalità sottostante che potrebbe andare persa con questa modifica? (* a parte le mappe di supporto, ecc.) – Dan

+1

La funzionalità di addizionalità principale che conosco per '.data()' è correlata ai collegamenti di memoria quando si usano cose diverse dalle semplici stringhe (ad esempio riferimenti di oggetti). Non solo impedisce i riferimenti DOM circolari, ma assicura anche che tutte le cose che hanno un riferimento tramite '.data()' vengano ripulite se si rimuove l'oggetto DOM tramite jQuery. Se usi solo stringhe, non penso che offra molte funzionalità aggiuntive per te. Se lo stai facendo molto, potresti voler considerare le prestazioni e l'utilizzo della memoria di un attributo DOM rispetto al modo jQuery. – jfriend00

Problemi correlati