Speichern beliebiger Daten für einige HTML-Tags

338

Ich mache eine Seite, die eine Interaktion durch Javascript hat. Nur als Beispiel: Links, die eine AJAX-Anfrage senden, um den Inhalt von Artikeln abzurufen und diese Daten dann in einem div anzuzeigen. In diesem Beispiel benötige ich natürlich jeden Link, um eine zusätzliche Information zu speichern: die ID des Artikels. Die Art und Weise, wie ich damit umgegangen bin, war, diese Informationen in den href-Link zu setzen:

<a class="article" href="#5">

Ich benutze dann jQuery, um die a.article-Elemente zu finden und den entsprechenden Event-Handler anzuhängen. (Lassen Sie sich hier nicht zu sehr auf die Benutzerfreundlichkeit oder Semantik ein, es ist nur ein Beispiel)

Wie auch immer, diese Methode funktioniert, riecht aber ein bisschen und ist überhaupt nicht erweiterbar (was passiert, wenn die Klickfunktion mehr als einen Parameter hat? Was ist, wenn einige dieser Parameter optional sind?)

Die sofort offensichtliche Antwort war die Verwendung von Attributen für das Element. Ich meine, dafür sind sie da, oder? (So'ne Art).

<a articleid="5" href="link/for/non-js-users.html">

In meiner letzten Frage habe ich gefragt, ob diese Methode gültig ist, und es stellt sich heraus, dass meine eigene DTD nicht definiert ist (ich nicht), dann nein, sie ist nicht gültig oder zuverlässig. Eine häufige Antwort war, die Daten in das classAttribut einzufügen (obwohl dies möglicherweise an meinem schlecht gewählten Beispiel lag), aber für mich riecht dies noch mehr. Ja, es ist technisch gültig, aber es ist keine großartige Lösung.

Eine andere Methode, die ich in der Vergangenheit verwendet hatte, bestand darin, tatsächlich JS zu generieren und es in die Seite eines <script>Tags einzufügen , um eine Struktur zu erstellen, die dem Objekt zugeordnet wird.

var myData = {
    link0 : {
        articleId : 5,
        target : '#showMessage'
        // etc...
    },
    link1 : {
        articleId : 13
    }
};

<a href="..." id="link0">

Aber dies kann ein echter Schmerz im Hintern sein und ist im Allgemeinen nur sehr chaotisch.

Um auf die Frage zu kommen, wie speichern Sie beliebige Informationen für HTML-Tags ?

nickf
quelle
2
Verwandte Frage: stackoverflow.com/questions/209428/…
Tamas Czinege

Antworten:

361

Welche HTML-Version verwenden Sie?

In HTML 5 ist es völlig gültig, benutzerdefinierten Attributen Daten vorangestellt zu haben , z

<div data-internalid="1337"></div>

In XHTML ist dies nicht wirklich gültig. Wenn Sie sich im XHTML 1.1-Modus befinden, wird sich der Browser wahrscheinlich darüber beschweren, aber im 1.0-Modus werden die meisten Browser dies nur stillschweigend ignorieren.

Wenn ich Sie wäre, würde ich dem skriptbasierten Ansatz folgen. Sie können es automatisch auf der Serverseite generieren lassen, damit es nicht zu kurz kommt, es zu warten.

Tamas Czinege
quelle
5
@Tchalvak: Stimmt, aber dieses Bit funktioniert in den meisten Browsern trotzdem.
Tamas Czinege
2
Andere haben behauptet, dass es keinen Grund gibt, auf den Support zu warten, da das einzige Problem darin besteht, dass die Validierung fehlschlägt und der IE nicht beschädigt wird. Siehe TJ Crowlers Antwort hier: stackoverflow.com/questions/1923278/…
Chris
42
Wenn Sie data-xxx-Attribute verwenden und diese abrufen möchten, können Sie einfach das "domElement.getAttribute ('data-Whatever')" ohne Framework eines Drittanbieters verwenden.
Ohad Kravchick
5
Denken Sie an die Leistung! jsperf.com/jquery-data-vs-jqueryselection-data/19
FilmJ
19
Erinnerung: Um die Daten 1337 über jquery abzurufen, müssen Sie 'data' aus dem Variablennamen entfernen. Verwenden Sie zum Beispiel: $(this).data('internalid'); Anstelle von:$(this).data('data-internalid');
Gideon Rosenthal
134

Wenn Sie jQuery bereits verwenden, sollten Sie die Methode "data" verwenden, die die empfohlene Methode zum Speichern beliebiger Daten auf einem dom-Element mit jQuery ist.

Um etwas zu speichern:

$('#myElId').data('nameYourData', { foo: 'bar' });

So rufen Sie Daten ab:

var myData = $('#myElId').data('nameYourData');

Das ist alles, was dazu gehört, aber schauen Sie in die jQuery-Dokumentation, um weitere Informationen / Beispiele zu erhalten.

Prestaul
quelle
20

Nur eine andere Möglichkeit, ich persönlich würde dies nicht verwenden, aber es funktioniert (stellen Sie sicher, dass Ihr JSON gültig ist, da eval () gefährlich ist).

<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);
Luca Matteis
quelle
1
+1 für Querdenken. Ich bin damit einverstanden, dass ich diese Methode wahrscheinlich nicht verwenden möchte, aber es ist eine vage praktikable Option!
Nickf
9
@nickf Sie können loszuwerden evalverwenden JSON.parsestattdessen jsfiddle.net/EAXmY
Simon
12

Beliebige Attribute sind nicht gültig, aber in modernen Browsern absolut zuverlässig. Wenn Sie die Eigenschaften über Javascript festlegen, müssen Sie sich auch nicht um die Validierung kümmern.

Eine Alternative besteht darin, Attribute in Javascript festzulegen. jQuery hat eine nette Dienstprogrammmethode nur für diesen Zweck, oder Sie können Ihre eigene rollen.

Eran Galperin
quelle
3
Warum nicht data-stattdessen Attribute verwenden?
Flimm
10

Ein Hack, der mit so ziemlich jedem möglichen Browser funktioniert, besteht darin, offene Klassen wie diese zu verwenden: <a class='data\_articleid\_5' href="link/for/non-js-users.html>;

Dies ist für Puristen nicht allzu elegant, aber universell unterstützt, standardkonform und sehr einfach zu manipulieren. Es scheint wirklich die bestmögliche Methode zu sein. Wenn Sie serialize, ändern , kopieren Sie Ihre Tags oder tun so ziemlich alles andere, datableiben angebracht, kopiert usw.

Das einzige Problem ist, dass Sie nicht serialisierbare Objekte nicht auf diese Weise speichern können und es möglicherweise Grenzen gibt, wenn Sie dort etwas wirklich Riesiges platzieren.

Eine zweite Möglichkeit besteht darin, gefälschte Attribute zu verwenden wie:<a articleid='5' href="link/for/non-js-users.html">

Dies ist eleganter, bricht aber den Standard und ich bin mir nicht 100% sicher, was die Unterstützung angeht. Viele Browser unterstützen es vollständig. Ich denke, IE6 unterstützt den JSZugriff darauf, aber nicht CSS selectors(was hier nicht wirklich wichtig ist). Vielleicht sind einige Browser völlig verwirrt. Sie müssen es überprüfen.

Noch gefährlicher wäre es, lustige Dinge wie Serialisieren und Deserialisieren zu tun.

Die Verwendung idsvon reinem JSHash funktioniert meistens, außer wenn Sie versuchen, Ihre Tags zu kopieren. Wenn dies der Fall ist tag <a href="..." id="link0">, kopieren Sie es mit Standardmethoden JSund versuchen Sie dann data, nur eine Kopie anzuhängen. Die andere Kopie wird geändert.

Es ist kein Problem, wenn Sie keine tags kopieren oder schreibgeschützte Daten verwenden. Wenn Sie tags kopieren und sie geändert werden, müssen Sie dies manuell erledigen.

taw
quelle
Valse auf Klasse zu speichern ist fantastisch
Saravanan Rajaraman
10

Mit jquery,

lagern: $('#element_id').data('extra_tag', 'extra_info');

abrufen: $('#element_id').data('extra_tag');

user2458978
quelle
6

Ich weiß, dass Sie derzeit jQuery verwenden, aber was ist, wenn Sie den Onclick-Handler inline definiert haben? Dann könnten Sie tun:

 <a href='/link/for/non-js-users.htm' onclick='loadContent(5);return false;'>
     Article 5</a>
Tvanfosson
quelle
6

Sie können versteckte Eingabe-Tags verwenden. Ich erhalte bei w3.org keine Validierungsfehler:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
  <head>
    <meta content="text/html;charset=UTF-8" http-equiv="content-type" />
    <title>Hello</title>
  </head>
  <body>
    <div>
      <a class="article" href="link/for/non-js-users.html">
        <input style="display: none" name="articleid" type="hidden" value="5" />
      </a>
    </div>
  </body>
</html>

Mit jQuery erhalten Sie die Artikel-ID mit etwas wie (nicht getestet):

$('.article input[name=articleid]').val();

Aber ich würde HTML5 empfehlen, wenn dies eine Option ist.

Phylae
quelle
13
Ich glaube eigentlich nicht, dass style="display: none"es für versteckte Eingabefelder benötigt wird.
Phylae
1
Guter Ansatz, absolut gültig in allen HTML-Versionen. Ich rate strikt von der Codierung mit der Annahme ab, dass alle Ihre Benutzer einen vollständig HTML5-Beschwerdebrowser haben. Und Anzeige: Für versteckte Felder wird keine benötigt.
Andreszs
Sehr schön. Dies ist die beste Lösung, die ich für XHTML gefunden habe, bei der Datenattribute keine gültige Option sind. IMO missbraucht es Tags / Attribute nicht auf unbeabsichtigte Weise, es hat fast keinen "Geruch". Und wie die anderen sagten: Anzeige: Keine wird nicht wirklich benötigt.
Arahman
4

Warum nicht die bereits vorhandenen aussagekräftigen Daten nutzen, anstatt beliebige Daten hinzuzufügen?

dh verwenden <a href="https://stackoverflow.com/articles/5/page-title" class="article-link">, und dann können Sie programmatisch alle Artikel Links auf der Seite erhalten (über den Klassennamen) und die Artikelnummer (Anpassung der regex /articles\/(\d+)/gegen this.href).


quelle
2
Problem dabei ist, dass es auch nicht wirklich erweiterbar ist
ehdv
4

Als jQuery-Benutzer würde ich das Metadaten-Plugin verwenden . Der HTML-Code sieht sauber aus, wird validiert und Sie können alles einbetten, was mit der JSON-Notation beschrieben werden kann.

Robin Smidsrød
quelle
3

Es sollte also vier Möglichkeiten geben, dies zu tun:

  1. Fügen Sie die Daten in das ID-Attribut ein.
  2. Fügen Sie die Daten in das beliebige Attribut ein
  3. Fügen Sie die Daten in das Klassenattribut ein
  4. Fügen Sie Ihre Daten in ein anderes Tag ein

http://www.shanison.com/?p=321

Shanison
quelle
@ h4ck3rm1k3 ... nicht im id-Attribut, da es innerhalb des Dokuments eindeutig sein muss und bei Bedarf in einer Seitenleiste oder so wiederholt werden sollte ... Es ist eine alte Frage, aber sie ist immer noch gültig
miguel-svq
2

Ich befürworte die Verwendung des Attributs "rel". Das XHTML wird validiert, das Attribut selbst wird selten verwendet und die Daten werden effizient abgerufen.

Dämonkoryu
quelle
Ich kann das nicht tun, um das Nofollow-Attribut auf den Links zu brechen
Carter Cole
2

Das ist ein guter Rat. Vielen Dank an @Prestaul

Wenn Sie jQuery bereits verwenden, sollten Sie die Methode "data" verwenden, die die empfohlene Methode zum Speichern beliebiger Daten auf einem dom-Element mit jQuery ist.

Sehr wahr, aber was ist, wenn Sie beliebige Daten in einfachem HTML speichern möchten? Hier ist noch eine Alternative ...

<input type="hidden" name="whatever" value="foobar"/>

Fügen Sie Ihre Daten in die Namens- und Wertattribute eines versteckten Eingabeelements ein. Dies kann nützlich sein, wenn der Server HTML generiert (z. B. ein PHP-Skript oder was auch immer) und Ihr JavaScript-Code diese Informationen später verwendet.

Zugegeben, nicht das sauberste, aber es ist eine Alternative. Es ist mit allen Browsern kompatibel und gültig für XHTML. Sie sollten KEINE benutzerdefinierten Attribute verwenden und auch keine Attribute mit dem Präfix 'data-' verwenden, da dies möglicherweise nicht in allen Browsern funktioniert. Darüber hinaus besteht Ihr Dokument die W3C-Validierung nicht.

BMiner
quelle
Ich weiß nicht genau, aber einige Browser beschweren sich möglicherweise, wenn Sie benutzerdefinierte Attribute mit einem "strengen" Doctype verwenden. In beiden Fällen ist XHTML nicht gültig.
BMiner
2

Sie können das Datenpräfix Ihres eigenen Attributs eines zufälligen Elements ( <span data-randomname="Data goes here..."></span>) verwenden, dies ist jedoch nur in HTML5 gültig. Daher können sich Browser über die Gültigkeit beschweren.

Sie können auch ein <span style="display: none;">Data goes here...</span>Tag verwenden. Auf diese Weise können Sie die Attributfunktionen jedoch nicht verwenden. Wenn css und js deaktiviert sind, ist dies auch keine wirklich gute Lösung.

Was ich persönlich bevorzuge, ist Folgendes:

<input type="hidden" title="Your key..." value="Your value..." />

Die Eingabe wird in jedem Fall ausgeblendet, die Attribute sind vollständig gültig und sie wird nicht gesendet, wenn sie sich innerhalb eines <form>Tags befindet, da sie keinen Namen hat, oder? Vor allem die Attribute sind sehr leicht zu merken und der Code sieht gut und leicht zu verstehen aus. Sie können sogar ein ID-Attribut einfügen, sodass Sie auch mit JavaScript problemlos darauf zugreifen und mit auf das Schlüssel-Wert-Paar zugreifen können input.title; input.value.

Yeti
quelle
Ich bin sicher, Sie haben nicht genug mit HTML-Tabellen und Auswahl gearbeitet. Sie werden das Datenattribut häufiger verwenden, um Arbeit zu sparen.
1
Ich benutze das Attribut 'data-' tatsächlich sehr oft. Aber es hängt davon ab, was Ihre Anforderungen sind. Zum Beispiel können Sie mit <input /> einen beliebigen Schlüssel haben, während dies für 'data-' vorzugsweise auf eine Kleinbuchstabenzeichenfolge ohne nicht alphanumerisches Zeichen beschränkt ist.
Yeti
1

Eine Möglichkeit könnte sein:

  • Erstellen Sie ein neues div, um alle erweiterten / beliebigen Daten aufzunehmen
  • Stellen Sie sicher, dass dieses Div unsichtbar ist (z. B. CSS plus ein Klassenattribut des Div).
  • Fügen Sie die erweiterten / beliebigen Daten in [X] HTML-Tags (z. B. als Text in Zellen einer Tabelle oder in andere Elemente, die Ihnen gefallen könnten) in dieses unsichtbare div ein
ChrisW
quelle
1

Ein anderer Ansatz kann darin bestehen, ein Schlüssel-Wert-Paar als einfache Klasse mit der folgenden Syntax zu speichern:

<div id="my_div" class="foo:'bar'">...</div>

Dies ist gültig und kann leicht mit jQuery-Selektoren oder einer benutzerdefinierten Funktion abgerufen werden.

Raphaël
quelle
0

Bei meinem früheren Arbeitgeber haben wir ständig benutzerdefinierte HTML-Tags verwendet, um Informationen zu den Formularelementen zu speichern. Der Haken: Wir wussten, dass der Benutzer gezwungen war, IE zu verwenden.

Für FireFox hat es damals nicht gut funktioniert. Ich weiß nicht, ob FireFox dies geändert hat oder nicht, aber beachten Sie, dass das Hinzufügen eigener Attribute zu HTML-Elementen möglicherweise vom Browser Ihres Lesers unterstützt wird oder nicht.

Wenn Sie steuern können, welchen Browser Ihr Reader verwendet (dh ein internes Web-Applet für ein Unternehmen), versuchen Sie es auf jeden Fall. Was kann es weh tun, richtig?

Jerry
quelle
0

So mache ich Ajax-Seiten ... es ist eine ziemlich einfache Methode ...

    function ajax_urls() {
       var objApps= ['ads','user'];
        $("a.ajx").each(function(){
               var url = $(this).attr('href');
               for ( var i=0;i< objApps.length;i++ ) {
                   if (url.indexOf("/"+objApps[i]+"/")>-1) {
                      $(this).attr("href",url.replace("/"+objApps[i]+"/","/"+objApps[i]+"/#p="));
                   }
               }
           });
}

Dies funktioniert im Grunde genommen mit allen URLs, die die Klasse 'ajx' haben, und es ersetzt ein Schlüsselwort und fügt das # -Zeichen hinzu. Wenn also js deaktiviert ist, verhalten sich die URLs wie gewohnt ... alle " apps "(jeder Abschnitt der Website) hat ein eigenes Schlüsselwort. Alles, was ich tun muss, ist, es dem obigen js-Array hinzuzufügen, um weitere Seiten hinzuzufügen ...

So sind zum Beispiel meine aktuellen Einstellungen eingestellt auf:

 var objApps= ['ads','user'];

Also, wenn ich eine URL habe wie:

www.domain.com/ads/3923/bla/dada/bla

Das js-Skript würde das / ads / part ersetzen, sodass meine URL am Ende sein würde

www.domain.com/ads/#p=3923/bla/dada/bla

Dann benutze ich das jquery bbq Plugin um die Seite entsprechend zu laden ...

http://benalman.com/projects/jquery-bbq-plugin/

Jason
quelle
0

Ich habe festgestellt, dass das Metadaten-Plugin eine hervorragende Lösung für das Problem ist, beliebige Daten mit dem HTML-Tag so zu speichern, dass es einfach abgerufen und mit jQuery verwendet werden kann.

Wichtig : Die tatsächliche Datei, die Sie einschließen, ist nur 5 KB und nicht 37 KB groß (dies entspricht der Größe des gesamten Download-Pakets).

Hier ist ein Beispiel dafür, wie Werte gespeichert werden, die ich beim Generieren eines Google Analytics-Tracking-Ereignisses verwende (Hinweis: data.label und data.value sind optionale Parameter).

$(function () {
    $.each($(".ga-event"), function (index, value) {
        $(value).click(function () {
            var data = $(value).metadata();
            if (data.label && data.value) {
                _gaq.push(['_trackEvent', data.category, data.action, data.label, data.value]);
            } else if (data.label) {
                _gaq.push(['_trackEvent', data.category, data.action, data.label]);
            } else {
                _gaq.push(['_trackEvent', data.category, data.action]);
            }
        });
    });
});

<input class="ga-event {category:'button', action:'click', label:'test', value:99}" type="button" value="Test"/>
Biofractal
quelle
0

In HTML können wir benutzerdefinierte Attribute mit dem Präfix 'data-' vor dem Attributnamen wie speichern

<p data-animal='dog'>This animal is a dog.</p>. Überprüfen Sie die Dokumentation

Wir können diese Eigenschaft verwenden, um Attribute mithilfe von jQuery wie folgt dynamisch festzulegen und abzurufen: Wenn wir ein ap-Tag wie haben

<p id='animal'>This animal is a dog.</p>

Um dann ein Attribut namens "Rasse" für das obige Tag zu erstellen, können wir schreiben:

$('#animal').attr('data-breed', 'pug');

Um die Daten jederzeit abzurufen, können wir schreiben:

var breedtype = $('#animal').data('breed');

Akash Ghosh
quelle
0

Warum benötigen Sie benutzerdefinierte Informationen in den HTML-Tags in der Ausgabe, solange Ihre eigentliche Arbeit am Server erledigt ist? Alles, was Sie auf dem Server wissen müssen, ist ein Index für jede Art von Liste von Strukturen mit Ihren benutzerdefinierten Informationen. Ich denke, Sie möchten die Informationen am falschen Ort speichern.

Ich werde erkennen, wie unglücklich es auch sein mag, dass in vielen Fällen die richtige Lösung nicht die richtige Lösung ist. In diesem Fall würde ich dringend empfehlen, Javascript zu generieren, um die zusätzlichen Informationen aufzunehmen.

Viele Jahre später:

Diese Frage wurde ungefähr drei Jahre gestellt, bevor data-...Attribute mit dem Aufkommen von HTML 5 zu einer gültigen Option wurden, sodass sich die Wahrheit geändert hat und die ursprüngliche Antwort, die ich gegeben habe, nicht mehr relevant ist. Jetzt würde ich vorschlagen , zu verwenden Datenattribute statt.

<a data-articleId="5" href="link/for/non-js-users.html">

<script>
    let anchors = document.getElementsByTagName('a');
    for (let anchor of anchors) {
        let articleId = anchor.dataset.articleId;
    }
</script>
Kris
quelle
Wie sollen Sie dann Daten an Javascript übergeben?
Nickf