wake-up-neo.com

Benutzerdefinierte Attribute - Ja oder Nein?

In letzter Zeit habe ich immer mehr über Leute gelesen, die benutzerdefinierte Attribute in ihren HTML-Tags verwenden, hauptsächlich, um einige zusätzliche Datenbits für die Verwendung in Javascript-Code einzubetten.

Ich hatte gehofft, ein Feedback zu erhalten, ob die Verwendung benutzerdefinierter Attribute eine gute Vorgehensweise ist und welche Alternativen es gibt.

Es scheint, als könnte es wirklich vereinfachen sowohl serverseitigen als auch clientseitigen Code, aber es ist auch nicht W3C-konform.

Sollten wir benutzerdefinierte HTML-Attribute in unseren Web-Apps verwenden? Warum oder warum nicht?

Für diejenigen, die benutzerdefinierte Attribute für eine gute Sache halten: Was sollten Sie beachten, wenn Sie sie verwenden?

Für diejenigen, die benutzerdefinierte Attribute für eine schlechte Sache halten: Welche Alternativen verwenden Sie, um etwas Ähnliches zu erreichen?

pdate: Ich interessiere mich hauptsächlich für die Argumentation hinter den verschiedenen Methoden sowie für Punkte, warum eine Methode besser ist als eine andere. Ich denke, wir können uns alle 4-5 verschiedene Wege ausdenken, um das gleiche Ziel zu erreichen. (versteckte Elemente, Inline-Skripte, zusätzliche Klassen, Analysieren von Informationen aus IDs usw.).

pdate 2: Es scheint, dass die HTML 5 data- Attribut Feature hat hier eine Menge Unterstützung (und ich stimme eher zu, es sieht aus wie eine solide Option). Bisher habe ich noch nicht viel von Widerlegungen für diesen Vorschlag gesehen. Gibt es irgendwelche Probleme/Fallstricke bei der Verwendung dieses Ansatzes? Oder ist es einfach eine "harmlose" Ungültigmachung der aktuellen W3C-Spezifikationen?

253
TM.

HTML 5 erlaubt explizit benutzerdefinierte Attribute, die mit data beginnen. So zum Beispiel <p data-date-changed="Jan 24 5:23 p.m.">Hello</p> ist gültig. Da es offiziell von einem Standard unterstützt wird, ist dies meiner Meinung nach die beste Option für benutzerdefinierte Attribute. Außerdem müssen Sie andere Attribute nicht mit Hacks überladen, damit Ihr HTML-Code semantisch bleibt.

Quelle: http://www.w3.org/TR/html5/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes

253
Chuck

Hier ist eine Technik, die ich in letzter Zeit verwendet habe:

<div id="someelement">

    <!-- {
        someRandomData: {a:1,b:2},
        someString: "Foo"
    } -->

    <div>... other regular content...</div>
</div>

Das Kommentarobjekt ist an das übergeordnete Element (d. H. #Someelement) gebunden.

Hier ist der Parser: http://pastie.org/511358

Um die Daten für ein bestimmtes Element abzurufen, rufen Sie einfach parseData mit einem Verweis auf dieses Element auf, der als einziges Argument übergeben wird:

var myElem = document.getElementById('someelement');

var data = parseData( myElem );

data.someRandomData.a; // <= Access the object staight away

Es kann prägnanter sein als das:

<li id="foo">
    <!--{specialID:245}-->
    ... content ...
</li>

Darauf zuzugreifen:

parseData( document.getElementById('foo') ).specialID; // <= 245

Der einzige Nachteil bei der Verwendung ist, dass es nicht mit selbstschließenden Elementen (z. B. <img/>), da die Kommentare innerhalb des Elements sein müssen, das als Daten dieses Elements betrachtet werden soll.


[~ # ~] edit [~ # ~] :

Bemerkenswerte Vorteile dieser Technik:

  • Einfach zu implementieren
  • Macht nicht HTML/XHTML ungültig
  • Einfach zu bedienen/zu verstehen (grundlegende JSON-Notation)
  • Unauffällig und semantisch sauberer als die meisten Alternativen

Hier ist der Parser-Code (kopiert aus dem obigen http://pastie.org/511358 Hyperlink, falls er jemals wird nicht verfügbar auf pastie.org):

var parseData = (function(){

    var getAllComments = function(context) {

            var ret = [],
                node = context.firstChild;

            if (!node) { return ret; }

            do {
                if (node.nodeType === 8) {
                    ret[ret.length] = node;
                }
                if (node.nodeType === 1) {
                    ret = ret.concat( getAllComments(node) );
                }
            } while( node = node.nextSibling );

            return ret;

        },
        cache = [0],
        expando = 'data' + +new Date(),
        data = function(node) {

            var cacheIndex = node[expando],
                nextCacheIndex = cache.length;

            if(!cacheIndex) {
                cacheIndex = node[expando] = nextCacheIndex;
                cache[cacheIndex] = {};
            }

            return cache[cacheIndex];

        };

    return function(context) {

        context = context || document.documentElement;

        if ( data(context) && data(context).commentJSON ) {
            return data(context).commentJSON;
        }

        var comments = getAllComments(context),
            len = comments.length,
            comment, cData;

        while (len--) {
            comment = comments[len];
            cData = comment.data.replace(/\n|\r\n/g, '');
            if ( /^\s*?\{.+\}\s*?$/.test(cData) ) {
                try {
                    data(comment.parentNode).commentJSON =
                        (new Function('return ' + cData + ';'))();
                } catch(e) {}
            }
        }

        return data(context).commentJSON || true;

    };

})();
95
James

Sie können jedes Attribut erstellen, wenn Sie ein Schema für Ihre Seite angeben.

Beispielsweise:

Addthis

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:addthis="http://www.addthis.com/help/api-spec">
...
<a addthis:title="" addthis:url="" ...>

Facebook (gerade Tags)

<html xmlns:og="http://opengraphprotocol.org/schema/" xmlns:fb="http://www.facebook.com/2008/fbml">
...
<fb:like href="http://developers.facebook.com/" width="450" height="80"/>
15
BrunoLM

Die einfachste Möglichkeit, die Verwendung benutzerdefinierter Attribute zu vermeiden, besteht darin, vorhandene Attribute zu verwenden.

verwenden Sie aussagekräftige, relevante Klassennamen.
Tun Sie zum Beispiel Folgendes: type='book' und type='cd', um Bücher und CDs darzustellen. Klassen sind viel besser für die Darstellung von etwas IST .

z.B. class='book'

Ich habe in der Vergangenheit benutzerdefinierte Attribute verwendet, aber ehrlich gesagt, ist dies wirklich nicht erforderlich, wenn Sie vorhandene Attribute auf semantisch sinnvolle Weise verwenden.

Nehmen wir an, Sie haben eine Website mit Links zu verschiedenen Arten von Geschäften. Sie könnten Folgendes verwenden:

<a href='wherever.html' id='bookstore12' class='book store'>Molly's books</a>
<a href='whereverelse.html' id='cdstore3' class='cd store'>James' Music</a>

cSS-Stil könnte Klassen wie:

.store { }
.cd.store { }
.book.store { }

Im obigen Beispiel sehen wir, dass beide Links zu Geschäften sind (im Gegensatz zu den anderen nicht verwandten Links auf der Site) und einer ein CD-Laden und der andere ein Buchladen ist.

10

Betten Sie die Daten in den Dom ein und verwenden Sie Metadaten für jQuery .

Alle guten Plug-Ins unterstützen das Metadaten-Plug-In (mit Optionen für einzelne Tags).

Es erlaubt auch unendlich komplexe Daten/Datenstrukturen sowie Schlüssel-Wert-Paare.

<li class="someclass {'some': 'random,'json':'data'} anotherclass">...</li>

OR

<li class="someclass" data="{'some':'random', 'json': 'data'}">...</li>

OR

<li class="someclass"><script type="data">{"some":"random","json":"data"}</script> ...</li>

Dann holen Sie sich die Daten wie folgt:

var data = $('li.someclass').metadata();
if ( data.some && data.some == 'random' )
alert('It Worked!');
6
antony.trupe

Ich sehe kein Problem darin, vorhandene XHTML-Funktionen zu verwenden, ohne etwas zu beschädigen oder Ihren Namespace zu erweitern. Schauen wir uns ein kleines Beispiel an:

<div id="some_content">
 <p>Hi!</p>
</div>

Wie füge ich zusätzliche Informationen zu some_content ohne zusätzliche Attribute hinzu? Was ist mit dem Hinzufügen eines weiteren Tags wie dem folgenden?

<div id="some_content">
 <div id="some_content_extended" class="hidden"><p>Some alternative content.</p></div>
 <p>Hi!</p>
</div>

Die Beziehung wird über eine gut definierte ID/Erweiterung "_extended" Ihrer Wahl und durch ihre Position in der Hierarchie beibehalten. Ich benutze diesen Ansatz oft zusammen mit jQuery und ohne tatsächlich Ajax-ähnliche Techniken zu verwenden.

4
merkuro

Ich verwende keine benutzerdefinierten Attribute, weil ich XHTML ausgebe, weil ich möchte, dass die Daten von Software von Drittanbietern maschinenlesbar sind (obwohl ich das XHTML-Schema erweitern könnte, wenn ich möchte).

Als Alternative zu benutzerdefinierten Attributen finde ich meistens die ID- und Klassenattribute (z. B. wie in anderen Antworten erwähnt) ausreichend.

Beachten Sie auch Folgendes:

  • Wenn die zusätzlichen Daten sowohl lesbar als auch maschinenlesbar sein sollen, müssen sie mit (sichtbaren) HTML-Tags und Text anstelle von benutzerdefinierten Attributen codiert werden.

  • Wenn es nicht für Menschen lesbar sein muss, kann es möglicherweise mit nsichtbar HTML-Tags und -Text codiert werden.

Einige Leute machen eine Ausnahme: Sie erlauben benutzerdefinierte Attribute, die dem DOM von Javascript auf der Clientseite zur Laufzeit hinzugefügt werden. Sie halten dies für OK: Da die benutzerdefinierten Attribute nur zur Laufzeit zum DOM hinzugefügt werden, enthält der HTML-Code keine benutzerdefinierten Attribute.

2
ChrisW

Wir haben einen webbasierten Editor entwickelt, der eine Teilmenge von HTML versteht - eine sehr strenge Teilmenge (die von E-Mail-Clients nahezu universell verstanden wird). Wir müssen Dinge wie <td width="@[email protected]"> In der Datenbank ausdrücken, aber wir können das nicht im DOM haben, da sonst der Browser, in dem der Editor ausgeführt wird, ausflippt (oder eher ausflippt als wahrscheinlich) über benutzerdefinierte Attribute ausflippen). Wir wollten Drag-and-Drop, also war das reine Ablegen im DOM ebenso wie jqueries .data() (die zusätzlichen Daten wurden nicht richtig kopiert). Wir brauchten wahrscheinlich auch die zusätzlichen Daten für die Fahrt in .html(). Am Ende haben wir beschlossen, während des Bearbeitungsprozesses <td width="1234" rs-width="@[email protected]"> Zu verwenden. Wenn wir dann alles POST entfernen wir width und führen eine reguläre Suche und Zerstörung durch s/rs-width=/width=/g.

Zuerst war der Typ, der das meiste davon schrieb, der Validierungs-Nazi in dieser Angelegenheit und versuchte alles, um unser benutzerdefiniertes Attribut zu umgehen, aber am Ende gab er sich damit ab, als nichts anderes für ALLE unsere Anforderungen zu funktionieren schien. Es half, als ihm klar wurde, dass das benutzerdefinierte Attribut niemals in einer E-Mail erscheinen würde. Wir haben darüber nachgedacht, unsere zusätzlichen Daten in class zu codieren, aber entschieden, dass dies das größere von zwei Übeln sein würde.

Ich persönlich bevorzuge Dinge sauber zu halten und Validatoren usw. zu übergeben, aber als Angestellter eines Unternehmens muss ich daran denken, dass meine Hauptverantwortung darin besteht, die Sache des Unternehmens voranzutreiben (so schnell wie möglich Geld zu verdienen). nicht das meines egoistischen Wunsches nach technischer Reinheit. Werkzeuge sollten für uns funktionieren; nicht wir für sie.

1

Ich weiß, dass die Leute dagegen sind, aber ich habe eine super kurze Lösung dafür gefunden. Wenn Sie ein benutzerdefiniertes Attribut wie "mine" verwenden möchten, zum Beispiel:

<a href="test.html" mine-one="great" mine-two="awesome">Test</a>

Anschließend können Sie diesen Code ausführen, um ein Objekt wie in jquery.data () zurückzugewinnen.

var custom_props = {} ;
$.each($(".selector")[0].attributes, function(i,x) {
    if (this.specified && x.name.indexOf("mine-") !== -1) 
        self.new_settings[x.name.replace("modal-","")] = x.value;
});
1
agrublev

Nein. Versuchen Sie stattdessen Folgendes:

<div id="foo"/>

<script type="text/javascript">
  document.getElementById('foo').myProperty = 'W00 H00! I can add JS properties to DOM nodes without using custom attributes!';
</script>
1
Anon

Ich benutze ständig benutzerdefinierte Felder, zum Beispiel <a i = "" .... Dann verweise ich mit jquery auf i. Ungültiges HTML, ja. Es funktioniert gut, ja.

0
Marius

Spec: Erstellen Sie ein ASP.NET-TextBox-Steuerelement, das den Text anhand der Eigenschaften "DecimalSeparator" und "ThousandsSeparator" mithilfe von JavaScript automatisch als Zahl formatiert.


Eine Möglichkeit, diese Eigenschaften vom Steuerelement in JavaScript zu übertragen, besteht darin, dass das Steuerelement benutzerdefinierte Eigenschaften rendert:

<input type="text" id="" decimalseparator="." thousandsseparator="," />

Benutzerdefinierte Eigenschaften sind mit JavaScript leicht zugänglich. Und während eine Seite, die Elemente mit benutzerdefinierten Eigenschaften verwendet, nicht validiert ist, wird das Rendering dieser Seite nicht beeinflusst.


Ich verwende diesen Ansatz nur , wenn ich einfache Typen wie Zeichenfolgen und Ganzzahlen mit HTML-Elementen zur Verwendung mit JavaScript verknüpfen möchte. Wenn ich die Identifizierung von HTML-Elementen vereinfachen möchte, verwende ich die Eigenschaften class und id.

0
cllpse

Bei komplexen Webanwendungen lege ich überall benutzerdefinierte Attribute ab.

Für öffentlich zugängliche Seiten verwende ich das Attribut "rel" und speichere dort alle meine Daten in JSON und dekodiere sie dann mit MooTools oder jQuery:

<a rel="{color:red, awesome:true, food: tacos}">blah</a>

Ich versuche, mich in letzter Zeit an das HTML 5-Datenattribut zu halten, nur um mich "vorzubereiten", aber das ist natürlich noch nicht geschehen.

0
Ryan Florence