Własne atrybuty-tak czy nie?

Ostatnio czytam coraz więcej o osobach używających własnych atrybutów w znacznikach HTML, głównie w celu osadzenia dodatkowych bitów danych do wykorzystania w kodzie javascript.

Miałem nadzieję zebrać kilka opinii na temat tego, czy używanie niestandardowych atrybutów jest dobrą praktyką, a także jakie są niektóre alternatywy.

Wydaje się, że może naprawdę uprościćzarówno po stronie serwera, jak i po stronie klienta, ale nie jest również zgodny z W3C.

Czy powinniśmy korzystasz z niestandardowych atrybutów HTML w naszych aplikacjach internetowych? Dlaczego czy nie?

Dla tych, którzy uważają, że atrybuty niestandardowe są dobrą rzeczą: o czym należy pamiętać podczas ich używania?

Dla tych, którzy myślą, że niestandardowe atrybuty są złe: jakich alternatyw używasz, aby osiągnąć coś podobnego?

Update: Jestem głównie zainteresowany rozumowaniem za różnymi metodami, a także wskazówkami, dlaczego jedna metoda jest lepsza od drugiej. I myślę, że wszyscy możemy wymyślić 4-5 różnych sposobów, aby osiągnąć to samo. (ukryte elementy, Skrypty wbudowane, dodatkowe klasy, parsowanie informacji z ids, itp.).

Update 2: wydaje się, że funkcja atrybutu HTML 5 data- ma tutaj duże wsparcie (i zazwyczaj się Zgadzam, wygląda to na solidną opcję). Do tej pory nie widziałem zbyt wiele na drodze do odrzucenia tej sugestii. Czy są jakieś problemy/pułapki, którymi należy się martwić przy użyciu tego podejścia? Czy jest to po prostu "nieszkodliwe" unieważnienie aktualnej specyfikacji W3C?

Author: surfmuggle, 2009-06-14

14 answers

HTML 5 jawnie zezwala na niestandardowe atrybuty zaczynające się od data. Tak więc, na przykład, <p data-date-changed="Jan 24 5:23 p.m.">Hello</p> jest poprawne. Ponieważ jest oficjalnie obsługiwany przez standard, myślę, że jest to najlepsza opcja dla niestandardowych atrybutów. I nie wymaga przeładowywania innych atrybutów hackami, więc twój HTML może pozostać semantyczny.

Źródło: http://www.w3.org/TR/html5/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes

 245
Author: Chuck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-23 15:37:46

Oto technika, którą ostatnio używam:

<div id="someelement">

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

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

Comment-object łączy się z elementem nadrzędnym (np. # someelement).

Oto parser: http://pastie.org/511358

Aby uzyskać dane dla dowolnego elementu wystarczy wywołać parseData z odniesieniem do tego elementu przekazanego jako jedyny argument:

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

var data = parseData( myElem );

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

Może być bardziej zwięzłe niż to:

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

Dostęp do niego:

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

Jedyną wadą nie można go używać z elementami samozamykającymi się (np. <img/>), ponieważ komentarze muszą być wewnątrz elementu, który należy traktować jako dane tego elementu.


EDIT :

Znaczące zalety tej techniki:

  • łatwy do wdrożenia
  • czy Nie unieważnia HTML/XHTML
  • W 1998 roku w Warszawie odbyła się pierwsza edycja festiwalu.]}
  • dyskretny i semantycznie czysty niż większość alternatywy

Oto kod parsera (skopiowany z http://pastie.org/511358 hiperłącze powyżej, w przypadku, gdy stanie się on niedostępny na 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
Author: James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-26 08:43:36

Możesz utworzyć dowolny atrybut, jeśli określisz schemat dla swojej strony.

Na przykład:

Addthis

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

Facebook (nawet tagi)

<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
Author: BrunoLM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 02:36:51

Najprostszym sposobem uniknięcia użycia własnych atrybutów jest użycie istniejących atrybutów.

Używaj znaczących, odpowiednich nazw klas.
Na przykład zrób coś w stylu: type='book' i type='cd', do reprezentowania książek i płyt CD. Klasy są znacznie lepsze do reprezentowania tego, czym jest coś .

Np. class='book'

Używałem niestandardowych atrybutów w przeszłości, ale szczerze mówiąc, naprawdę nie ma potrzeby dla nich, jeśli używasz istniejących atrybutów w znaczeniu semantycznym sposób.

Aby podać bardziej konkretny przykład, powiedzmy, że masz stronę z linkami do różnych rodzajów sklepów. Możesz użyć następującego:

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

Stylizacja Css może używać klas takich jak:

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

W powyższym przykładzie widzimy, że oba są linkami do sklepów (w przeciwieństwie do innych niepowiązanych linków na stronie), a jeden jest sklepem z płytami cd, a drugi jest sklepem z książkami.

 10
Author: Jonathan Fingland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 16:29:03

Umieść dane w dom i użyj metadanych dla jQuery .

Wszystkie dobre wtyczki obsługują wtyczkę metadanych (zezwalając na opcje dla tagów).

Pozwala również na nieskończenie złożone struktury danych/danych, a także pary klucz-wartość.

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

Lub

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

Lub

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

Następnie uzyskaj dane w ten sposób:

var data = $('li.someclass').metadata();
if ( data.some && data.some == 'random' )
alert('It Worked!');
 6
Author: antony.trupe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-26 08:44:39

Nie widzę problemu w używaniu istniejących funkcji XHTML bez łamania czegokolwiek lub rozszerzania przestrzeni nazw. Spójrzmy na mały przykład:

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

Jak dodać dodatkowe informacje do some_content bez dodatkowych atrybutów? Co powiesz na dodanie innego tagu, takiego jak poniżej?

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

Utrzymuje relację poprzez dobrze zdefiniowane id / rozszerzenie "_extended" do wyboru i przez swoją pozycję w hierarchii. Często używam tego podejścia razem z jQuery i bez właściwie używając technik Ajax.

 4
Author: merkuro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-14 04:11:39

Nie używam niestandardowych atrybutów, ponieważ wydaję XHTML, ponieważ chcę, aby dane były odczytywalne maszynowo przez oprogramowanie innych firm(chociaż mógłbym rozszerzyć schemat XHTML, gdybym chciał).

Jako alternatywa dla niestandardowych atrybutów, najczęściej znajduję atrybuty id i klasy (np. jak wspomniano w innych odpowiedziach) wystarczające.

Weź również pod uwagę to:

  • Jeśli dodatkowe dane mają być zarówno czytelne dla człowieka, jak i dla maszyn, to muszą być kodowane za pomocą (widocznych) znaczników HTML i tekstu zamiast własnych atrybutów.

  • Jeśli nie musi być czytelny dla człowieka, być może można go zakodować za pomocą niewidzialnych znaczników HTML i tekstu.

Niektórzy robią wyjątek: zezwalają na niestandardowe atrybuty, dodawane do DOM przez Javascript po stronie klienta w czasie wykonywania. Uważają, że jest to OK: ponieważ atrybuty niestandardowe są dodawane do DOM tylko w czasie wykonywania, HTML nie zawiera niestandardowych atrybuty.

 2
Author: ChrisW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-14 04:12:41

Nie. Spróbuj czegoś takiego zamiast tego:

<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
Author: Anon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-14 04:12:14

Stworzyliśmy edytor internetowy, który rozumie podzbiór HTML - bardzo ścisły podzbiór (rozumiany niemal powszechnie przez klientów pocztowych). Musimy wyrażać rzeczy takie jak <td width="@INSWIDTH_42@"> w bazie danych, ale nie możemy tego mieć w DOM, w przeciwnym razie przeglądarka, w której działa edytor, wariuje (lub jest bardziej narażona na wariacje niż na niestandardowe atrybuty). Chcieliśmy przeciągnąć i upuścić, więc umieszczenie go wyłącznie w DOM było wyłączone, podobnie jak jQuery .data() (dodatkowe dane nie dostały skopiowane poprawnie). Prawdopodobnie potrzebowaliśmy również dodatkowych danych, aby przyjść na przejażdżkę w .html(). W końcu zdecydowaliśmy się na użycie <td width="1234" rs-width="@INSWIDTH_42@"> podczas procesu edycji, a następnie po opublikowaniu wszystkiego usuwamy width i wykonujemy regex search-and-destroy s/rs-width=/width=/g.

Na początku facet piszący większość tego był walidatorem-nazistą w tej kwestii i próbował wszystkiego, aby uniknąć naszego zwyczajowego atrybutu, ale w końcu zgodził się, gdy nic innego nie wydawało się działać dla wszystkich naszych wymagań. Pomogło, gdy zdaliśmy sobie sprawę, że Niestandardowy atrybut nigdy nie pojawi się w e-mail rozważaliśmy zakodowanie naszych dodatkowych danych w class, ale zdecydowaliśmy, że będzie to większe z dwóch złych.

Osobiście, ja wolę mieć rzeczy czyste i zdające walidatory itp. ale jako pracownik firmy muszę pamiętać, że moim głównym zadaniem jest wspieranie sprawy firmy (zarabianie jak najszybciej pieniędzy), a nie moje egoistyczne pragnienie czystości technicznej. Narzędzia powinny pracować dla nas, nie dla nich.

 1
Author: Bernd Jendrissek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-12 14:16:39

Wiem, że ludzie są temu przeciwni, ale wymyśliłem na to bardzo krótkie rozwiązanie. Jeśli chcesz użyć niestandardowego atrybutu, takiego jak "mine", na przykład:

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

Następnie możesz uruchomić ten kod, aby odzyskać obiekt tak jak jquery.data ().

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
Author: agrublev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-19 20:42:47

Spec: Create an ASP.NET TextBox kontrolka, która dynamicznie automatycznie formatuje swój tekst jako liczbę, według właściwości "DecimalSeparator" i "ThousandsSeparator", używając JavaScript.


Jednym ze sposobów przeniesienia tych właściwości z kontrolki do JavaScript jest renderowanie właściwości niestandardowych:

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

Właściwości niestandardowe są łatwo dostępne przez JavaScript. I podczas gdy strona używająca elementów o własnościach niestandardowych nie sprawdzi , renderowanie tej strony nie będzie miało wpływu.


I only używać tego podejścia, gdy chcę skojarzyć proste typy, takie jak ciągi i liczby całkowite z elementami HTML do użytku z JavaScript. Jeśli chcę ułatwić identyfikację elementów HTML, użyję właściwości class i id .

 0
Author: cllpse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-11 17:33:56

Używam pól niestandardowych cały czas na przykład

 0
Author: Marius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-26 00:23:37

W przypadku złożonych aplikacji internetowych upuszczam niestandardowe atrybuty wszędzie.

Dla bardziej publicznych stron stojących używam atrybutu " rel " i wrzucam wszystkie moje dane w JSON, a następnie dekoduję je za pomocą MooTools lub jQuery:

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

Staram się trzymać atrybutu danych HTML 5 ostatnio tylko po to, aby "przygotować", ale nie przyszło to jeszcze naturalnie.

 0
Author: Ryan Florence,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-26 08:45:35

Niestandardowe atrybuty, moim skromnym zdaniem, nie powinny być używane, ponieważ nie sprawdzają się. Alternatywnie można zdefiniować wiele klas dla jednego elementu, takich jak:

<div class='class1 class2 class3'>
    Lorem ipsum
</div>
 -2
Author: Alan Haggai Alavi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-15 00:50:42