javascript - Cum să stochezi date arbitrare pentru unele etichete HTML
Îmi fac o pagină care are unele interacțiuni oferite de JavaScript. Doar ca exemplu: linkuri care trimit o cerere AJAX pentru a obține conținutul articolelor și apoi afișează acele date într-un div. Evident, în acest exemplu, am nevoie ca fiecare link să stocheze o informație suplimentară: id-ul articolului. Modul în care am gestionat-o, în acest caz, a fost să pun acea informație în linkul href astfel:
<a class="article" href="#5">
Apoi folosesc jQuery pentru a găsi elementele a.article și pentru a atașa handler-ul de eveniment potrivit. (nu te concentra prea mult pe uzabilitate sau semnificație aici, este doar un exemplu)
Oricum, această metodă funcționează, dar miroase puțin și nu este deloc extensibilă (ce se întâmplă dacă funcția de click are mai mult de un parametru? ce se întâmplă dacă unele dintre acele parametri sunt opționali?)
Răspunsul evident imediat a fost să folosești atribute pe element. Adică, pentru asta sunt ele, nu-i așa? (Într-un fel).
<a articleid="5" href="link/for/non-js-users.html">
În întrebarea mea recentă am întrebat dacă această metodă era valabilă, și se pare că, dacă nu îmi definesc propriul DTD (ceea ce nu fac), atunci nu, nu este valabilă sau de încredere. Un răspuns comun a fost să pun datele în atributul class (deși acest lucru ar fi putut fi din cauza exemplului meu ales prost), dar pentru mine, asta miroase și mai tare. Da, este tehnic valid, dar nu este o soluție grozavă.
O altă metodă pe care o folosisem în trecut era să generez de fapt niște JS și să îl inserez în pagină într-un tag <script>, creând o structură care s-ar asocia cu obiectul.
var myData = {
link0 : {
articleId : 5,
target : '#showMessage'
// etc...
},
link1 : {
articleId : 13
}
};
<a href="..." id="link0">
Dar acest lucru poate fi cu adevărat o bătaie de cap de întreținut și, în general, este doar foarte dezordonat.
Deci, ca să ajungem la întrebare, cum stochezi bucăți arbitrare de informații pentru etichetele HTML?
Răspuns #1
Ce versiune de HTML folosești?
În HTML 5, este complet valid să ai atribute personalizate prefixate cu data-, de exemplu.
<div data-internalid="1337"></div>
În XHTML, aceasta nu este chiar validă. Dacă sunteți în modul XHTML 1.1, browserul probabil că se va plânge despre asta, dar în modul 1.0, majoritatea browserelor pur și simplu o vor ignora fără să afișeze ceva.
Dacă aș fi în locul tău, aș urma abordarea bazată pe scripturi. Ai putea să o generezi automat pe partea de server astfel încât să nu fie o bătaie de cap să o întreții.
Răspunsul #2
Dacă folosiți deja jQuery, ar trebui să folosiți metoda „data”, care este metoda recomandată pentru stocarea datelor arbitrare pe un element DOM cu jQuery.
Pentru a depozita ceva:
$('#myElId').data('nameYourData', { foo: 'bar' });
Pentru a prelua datele:
var myData = $('#myElId').data('nameYourData');
Asta este tot ceea ce este, dar aruncă o privire la documentația jQuery pentru mai multe informații/exemple.
Răspunsul #3
Doar o altă metodă, personal nu aș folosi asta, dar funcționează (asigură-te că JSON-ul tău este valid deoarece eval() este periculos).
<a class="article" href="link/for/non-js-users.html">
<span style="display: none;">{"id": 1, "title":"Something"}</span>
Text of Link
</a>
// javascript
var article = document.getElementsByClassName("article")[0];
var data = eval(article.childNodes[0].innerHTML);
Răspunsul #4
Atributele arbitrare nu sunt valide, dar sunt perfect fiabile în browserele moderne. Dacă setezi proprietățile prin JavaScript, atunci nu trebuie să te îngrijorezi nici de validare.
O alternativă este să setezi atributele în JavaScript. jQuery are o metodă utilitară foarte bună doar în acest scop, sau îți poți crea propria metodă.
Răspunsul #5
O metodă care va funcționa cu aproape orice browser posibil este să folosești clase deschise astfel: <a class='data\_articleid\_5' href="link/for/non-js-users.html>;
Acest lucru nu este deloc elegant pentru puriști, dar este acceptat pe scară largă, conform standardelor și foarte ușor de manipulat. Se pare cu adevărat metoda cea mai bună posibilă. Dacă serializezi, modifici, copiați etichetele tale sau faci practic orice altceva, data va rămâne atașată, copiată etc.
Singura problemă este că nu poți stoca obiecte neserializabile în acest mod, și ar putea exista limitări dacă pui ceva cu adevărat uriaș acolo.
O a doua modalitate este să folosești atribute false precum: <a articleid='5' href="link/for/non-js-users.html">
Aceasta este mai elegantă, dar încalcă standardul și nu sunt 100% sigur de suport. Multe browsere îl suportă complet, cred că IE6 suportă accesul JS pentru el, dar nu CSS selectori (ceea ce nu contează prea mult aici), poate unele browsere vor fi complet confuze, trebuie să verifici asta.
Făcând lucruri amuzante, cum ar fi serializarea și deserializarea, ar fi și mai periculos.
Folosirea ids pentru un hash pur JS funcționează în mare parte, cu excepția cazului când încerci să copiezi tag-urile tale. Dacă ai tag <a href="..." id="link0">, copiază-l prin metode standard JS, și apoi încearcă să modifici data atașată doar la o copie, cealaltă copie va fi modificată.
Nu este o problemă dacă nu copiezi tag-uri sau folosești date read only. Dacă copiezi tag-uri și acestea sunt modificate, va trebui să le gestionezi manual.
Răspunsul #6
Folosind jquery,
a stoca: $ ('#element_id').data('extra_tag', 'extra_info');
pentru a prelua: $ ('#element_id').data('extra_tag');
