Jak przechowywać dowolne dane dla niektórych tagów HTML

338

Tworzę stronę, która zawiera pewne interakcje zapewniane przez javascript. Na przykład: linki, które wysyłają żądanie AJAX w celu pobrania treści artykułów, a następnie wyświetlenia tych danych w div. Oczywiście w tym przykładzie potrzebuję każdego linku do przechowywania dodatkowej informacji: identyfikatora artykułu. Sposób, w jaki sobie z tym poradziłem, to umieszczenie tych informacji w odnośniku link:

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

Następnie używam jQuery, aby znaleźć elementy a.article i dołączyć odpowiednią procedurę obsługi zdarzeń. (nie przejmuj się zbytnio użytecznością lub semantyką tutaj, to tylko przykład)

W każdym razie ta metoda działa, ale trochę pachnie i wcale nie jest rozszerzalna (co się stanie, jeśli funkcja kliknięcia ma więcej niż jeden parametr? Co, jeśli niektóre z tych parametrów są opcjonalne?)

Natychmiast oczywistą odpowiedzią było użycie atrybutów na elemencie. To znaczy po to są, prawda? (Rodzaj).

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

W moim ostatnim pytaniu zapytałem, czy ta metoda jest poprawna, i okazuje się, że poza zdefiniowaniem własnego DTD (nie wiem), to nie, nie jest poprawna ani wiarygodna. Częstą reakcją było umieszczenie danych w classatrybucie (choć mogło to wynikać z mojego źle wybranego przykładu), ale dla mnie to pachnie jeszcze bardziej. Tak, jest technicznie poprawny, ale nie jest to świetne rozwiązanie.

Inną metodą, której użyłem w przeszłości, było wygenerowanie JS i wstawienie go do strony w <script>tagu, tworząc strukturę, która byłaby powiązana z obiektem.

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

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

Ale może to być prawdziwy problem w utrzymaniu tyłka i ogólnie jest po prostu bardzo niechlujny.

Aby przejść do pytania, w jaki sposób przechowujesz dowolne informacje dla tagów HTML ?

pseudonim
źródło
2
Powiązane pytanie: stackoverflow.com/questions/209428/…
Tamas Czinege

Odpowiedzi:

361

Jakiej wersji HTML używasz?

W HTML 5 jest całkowicie poprawne, aby niestandardowe atrybuty były poprzedzone danymi - np

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

W XHTML nie jest to naprawdę poprawne. Jeśli jesteś w trybie XHTML 1.1, przeglądarka prawdopodobnie narzeka na to, ale w trybie 1.0 większość przeglądarek po prostu dyskretnie go zignoruje.

Gdybym był tobą, stosowałbym podejście oparte na skryptach. Możesz sprawić, aby był automatycznie generowany po stronie serwera, aby nie było problemu z utrzymaniem.

Tamas Czinege
źródło
5
@Tchalvak: To prawda, ale ten bit będzie działał w większości przeglądarek.
Tamas Czinege
2
Inni twierdzili, że nie ma powodu, aby czekać na wsparcie, ponieważ jedynym problemem, który powoduje, jest brak weryfikacji i nie psuje IE. Zobacz odpowiedź TJ Crowlera tutaj: stackoverflow.com/questions/1923278/...
Chris
42
Jeśli używasz atrybutów data-xxx i chcesz je odzyskać, możesz po prostu użyć „domElement.getAttribute („ dane-cokolwiek ”)” bez żadnych ram zewnętrznych.
Ohad Kravchick
5
Pamiętaj o wydajności! jsperf.com/jquery-data-vs-jqueryselection-data/19
FilmJ
19
Przypomnienie: Aby odzyskać dane, 1337 za pomocą jquery, należy usunąć „dane” z nazwy zmiennej. Na przykład użyj: $(this).data('internalid'); Zamiast:$(this).data('data-internalid');
Gideon Rosenthal,
134

Jeśli już używasz jQuery, powinieneś skorzystać z metody „data”, która jest zalecaną metodą do przechowywania dowolnych danych w elemencie dom z jQuery.

Aby coś zapisać:

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

Aby pobrać dane:

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

To wszystko, ale jest więcej informacji / przykładów w dokumentacji jQuery .

Prestaul
źródło
20

Po prostu inaczej, osobiście nie użyłbym tego, ale działa (upewnij się, że twój JSON jest prawidłowy, ponieważ eval () jest niebezpieczny).

<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
źródło
1
+1 za myślenie boczne. Zgadzam się, że prawdopodobnie nie chciałbym używać tej metody, ale jest to niewykonalna opcja!
nickf
9
@nickf Możesz pozbyć się evalużywania JSON.parsezamiast tego jsfiddle.net/EAXmY
Simon
12

Arbitralne atrybuty nie są prawidłowe, ale są całkowicie niezawodne w nowoczesnych przeglądarkach. Jeśli ustawiasz właściwości za pomocą javascript, nie musisz się również martwić o sprawdzanie poprawności.

Alternatywą jest ustawienie atrybutów w javascript. jQuery ma fajną metodę użyteczną tylko do tego celu, lub możesz rzucić własną.

Eran Galperin
źródło
3
Dlaczego data-zamiast tego nie użyć atrybutów?
Flimm
10

Hack, który będzie działał z praktycznie każdą możliwą przeglądarką, polega na użyciu otwartych klas takich jak to: <a class='data\_articleid\_5' href="link/for/non-js-users.html>;

To nie jest zbyt eleganckie dla purystów, ale jest powszechnie obsługiwane, zgodne ze standardami i bardzo łatwe w obsłudze. To naprawdę wydaje się najlepszą z możliwych metod. Jeśli serialize, modyfikować , kopiować tagów, czy też prawie nic innego, datapozostanie załączony, kopiować itd.

Jedynym problemem jest to, że nie można w ten sposób przechowywać obiektów, które nie można serializować , i mogą istnieć ograniczenia, jeśli umieści się tam coś naprawdę dużego.

Drugim sposobem jest użycie fałszywych atrybutów, takich jak:<a articleid='5' href="link/for/non-js-users.html">

Jest to bardziej eleganckie, ale łamie standard i nie jestem w 100% pewien co do wsparcia. Wiele przeglądarek obsługuje go w pełni, myślę, że IE6 obsługuje JSdostęp, ale nie CSS selectors(co tak naprawdę nie ma znaczenia), może niektóre przeglądarki będą całkowicie zdezorientowane, musisz to sprawdzić.

Robienie zabawnych rzeczy, takich jak serializowanie i deserializowanie, byłoby jeszcze bardziej niebezpieczne.

Używanie idsczystego JSskrótu działa głównie, z wyjątkiem prób kopiowania tagów. Jeśli tak tag <a href="..." id="link0">, skopiuj go standardowymi JSmetodami, a następnie spróbuj zmodyfikować datazałącznik do tylko jednej kopii, a druga kopia zostanie zmodyfikowana.

Nie stanowi problemu, jeśli nie kopiujesz danych taglub nie używasz danych tylko do odczytu . Jeśli skopiujesz tags i zostaną one zmodyfikowane, będziesz musiał to zrobić ręcznie.

wyprawiać
źródło
przechowywanie walców na zajęciach jest niesamowite
Saravanan Rajaraman
10

Za pomocą jquery,

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

pobrać: $('#element_id').data('extra_tag');

użytkownik2458978
źródło
6

Wiem, że obecnie używasz jQuery, ale co, jeśli zdefiniowałeś wbudowany moduł obsługi onclick. Następnie możesz zrobić:

 <a href='/link/for/non-js-users.htm' onclick='loadContent(5);return false;'>
     Article 5</a>
tvanfosson
źródło
6

Możesz użyć ukrytych znaczników wejściowych. Nie otrzymuję żadnych błędów sprawdzania poprawności na w3.org:

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

Dzięki jQuery otrzymasz identyfikator artykułu z czymś takim (nie testowany):

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

Ale poleciłbym HTML5, jeśli jest to opcja.

phylae
źródło
13
Właściwie nie uważam, że style="display: none"jest to potrzebne w przypadku ukrytych pól wprowadzania.
phylae,
1
Dobre podejście, całkowicie poprawne we wszystkich wersjach HTML. Szczególnie odradzam kodowanie przy założeniu, że wszyscy twoi użytkownicy będą mieli przeglądarkę z pełną skargą HTML5. I wyświetlanie: żadne nie jest potrzebne w przypadku ukrytych pól.
andreszs
Bardzo dobrze. To najlepsze rozwiązanie, jakie znalazłem dla XHTML, w którym atrybuty danych nie są prawidłową opcją. IMO nie nadużywa tagów / atrybutów w niezamierzony sposób, prawie w ogóle nie ma „zapachu”. I jak powiedzieli inni: wyświetl: żaden nie jest tak naprawdę potrzebny.
Arahman
4

Dlaczego nie skorzystać z istotnych danych już tam, zamiast dodawać dowolne dane?

tj używać <a href="https://stackoverflow.com/articles/5/page-title" class="article-link">, a następnie można programowo uzyskać wszystkie linki artykułów na stronie (poprzez nazwę klasy) oraz identyfikator artykułu (dopasowanie regex /articles\/(\d+)/przeciw this.href).


źródło
2
Problem polega na tym, że nie jest również tak naprawdę rozszerzalny
ehdv
4

Jako użytkownik jQuery użyłbym wtyczki Metadata . HTML wygląda czysto, sprawdza poprawność i można osadzić wszystko, co można opisać za pomocą notacji JSON.

Robin Smidsrød
źródło
3

Dlatego powinny istnieć cztery możliwości:

  1. Umieść dane w atrybucie id.
  2. Umieść dane w dowolnym atrybucie
  3. Umieść dane w atrybucie klasy
  4. Umieść swoje dane w innym tagu

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

Shanison
źródło
@ h4ck3rm1k3 ... nie w atrybucie id, ponieważ musi być unikatowy dla dokumentu i powinien zostać powtórzony w razie potrzeby na pasku bocznym lub coś w tym stylu ... To stare pytanie, ale nadal aktualne
miguel-svq
2

Opowiadam się za użyciem atrybutu „rel”. XHTML sprawdza poprawność, sam atrybut jest rzadko używany, a dane są skutecznie odzyskiwane.

demonkoryu
źródło
nie mogę zrobić tego id złamać atrybut nofollow na linkach
Carter Cole
2

To dobra rada. Dzięki @Prestaul

Jeśli już używasz jQuery, powinieneś skorzystać z metody „data”, która jest zalecaną metodą do przechowywania dowolnych danych w elemencie dom z jQuery.

Bardzo prawda, ale co, jeśli chcesz przechowywać dowolne dane w zwykłym HTML? Oto kolejna alternatywa ...

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

Umieść swoje dane w atrybutach nazwy i wartości ukrytego elementu wejściowego. Może to być przydatne, jeśli serwer generuje HTML (tj. Skrypt PHP lub cokolwiek innego), a kod JavaScript będzie korzystał z tych informacji później.

Wprawdzie nie najczystszy, ale jest to alternatywa. Jest kompatybilny ze wszystkimi przeglądarkami i jest prawidłowym XHTML. NIE powinieneś używać atrybutów niestandardowych, ani też nie powinieneś używać atrybutów z prefiksem „data-”, ponieważ może to nie działać we wszystkich przeglądarkach. Ponadto twój dokument nie przejdzie walidacji W3C.

BMiner
źródło
nie jestem pewien, ale niektóre przeglądarki mogą narzekać, jeśli użyjesz niestandardowych atrybutów z „ścisłym” typem dokumentu. Tak czy inaczej, to nie jest prawidłowy XHTML.
BMiner
2

Możesz użyć prefiksu danych własnego atrybutu losowego elementu ( <span data-randomname="Data goes here..."></span>), ale jest to poprawne tylko w HTML5. Dlatego przeglądarki mogą narzekać na ważność.

Możesz także użyć <span style="display: none;">Data goes here...</span>tagu. Ale w ten sposób nie można używać funkcji atrybutów, a jeśli css i js są wyłączone, to też nie jest naprawdę fajne rozwiązanie.

Ale osobiście wolę to:

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

Dane wejściowe we wszystkich przypadkach będą ukryte, atrybuty są całkowicie poprawne i nie zostaną wysłane, jeśli znajdują się w <form>tagu, ponieważ nie mają żadnej nazwy, prawda? Przede wszystkim atrybuty są naprawdę łatwe do zapamiętania, a kod wygląda ładnie i łatwo go zrozumieć. Możesz nawet umieścić w nim atrybut ID, abyś mógł łatwo uzyskać do niego dostęp również za pomocą JavaScript i uzyskać dostęp do pary klucz-wartość za pomocą input.title; input.value.

Yeti
źródło
Jestem pewien, że nie pracowałeś wystarczająco z tabelami HTML i wyborem. Będziesz częściej używał atrybutu data, aby zaoszczędzić trochę pracy.
1
W rzeczywistości często używam atrybutu „data-”. Ale to zależy od twoich wymagań. Na przykład, za pomocą <input /> możesz mieć dowolny klucz, podczas gdy dla „data-” jest to ograniczone do małych liter bez żadnego alfanumerycznego znaku.
Yeti
1

Jedną z możliwości może być:

  • Utwórz nowy div, aby przechowywać wszystkie rozszerzone / dowolne dane
  • Zrób coś, aby upewnić się, że div jest niewidoczny (np. CSS plus atrybut klasy div)
  • Umieść rozszerzone / dowolne dane w tagach HTML [X] (np. Jako tekst w komórkach tabeli lub cokolwiek innego, co może ci się spodobać) w tym niewidocznym div
ChrisW
źródło
1

Innym podejściem może być przechowywanie pary klucz: wartość jako prostej klasy przy użyciu następującej składni:

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

Jest to poprawne i można je łatwo odzyskać za pomocą selektorów jQuery lub niestandardowej funkcji.

Raphaël
źródło
0

U mojego poprzedniego pracodawcy cały czas korzystaliśmy z niestandardowych tagów HTML, aby przechowywać informacje o elementach formularza. Haczyk: wiedzieliśmy, że użytkownik był zmuszony do korzystania z IE.

W tym czasie nie działało to dobrze dla FireFox. Nie wiem, czy FireFox to zmienił, czy nie, ale pamiętaj, że dodanie własnych atrybutów do elementów HTML może, ale nie musi, być obsługiwane przez przeglądarkę twojego czytnika.

Jeśli możesz kontrolować, z jakiej przeglądarki korzysta Twój czytnik (tj. Wewnętrzny aplet sieciowy dla korporacji), to spróbuj za wszelką cenę. Co może boleć, prawda?

Nocnik
źródło
0

Tak robię strony ajax ... to całkiem prosta metoda ...

    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="));
                   }
               }
           });
}

Jak to działa, w zasadzie patrzy na wszystkie adresy URL, które mają klasę „ajx” i zastępuje słowo kluczowe i dodaje znak # ... więc jeśli js jest wyłączony, adresy URL działałyby tak, jak zwykle ... wszystkie " aplikacje ”(każda sekcja witryny) ma własne słowo kluczowe ... więc muszę tylko dodać powyższą tablicę js, aby dodać więcej stron ...

Na przykład moje obecne ustawienia są ustawione na:

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

Więc jeśli mam adres URL, taki jak:

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

skrypt js zastąpiłby / ads / part, więc mój adres URL byłby ostatecznie

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

Następnie używam wtyczki jquery bbq, aby odpowiednio załadować stronę ...

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

Jason
źródło
0

Zauważyłem, że wtyczka metadanych jest doskonałym rozwiązaniem problemu przechowywania dowolnych danych ze znacznikiem html w sposób, który ułatwia pobieranie i używanie z jQuery.

Ważny : Rzeczywisty plik, który dołączasz, to tylko 5 kb, a nie 37 kb (co jest rozmiarem kompletnego pakietu do pobrania)

Oto przykład jego użycia do przechowywania wartości, których używam podczas generowania zdarzenia śledzenia Google Analytics (uwaga: data.label i data.value to opcjonalne parametry)

$(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"/>
biofraktal
źródło
0

W html możemy przechowywać niestandardowe atrybuty z przedrostkiem „data-” przed nazwą atrybutu, np

<p data-animal='dog'>This animal is a dog.</p>. Czek dokumentację

Możemy użyć tej właściwości, aby dynamicznie ustawiać i uzyskiwać atrybuty za pomocą jQuery typu: Jeśli mamy tag ap podobny

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

Następnie, aby utworzyć atrybut o nazwie „hodowla” dla powyższego tagu, możemy napisać:

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

Aby pobrać dane w dowolnym momencie, możemy napisać:

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

Akash Ghosh
źródło
0

Tak długo, jak faktycznie wykonujesz swoją pracę na serwerze, dlaczego i tak potrzebujesz niestandardowych informacji w tagach HTML w danych wyjściowych? wszystko, co musisz wiedzieć z powrotem na serwerze, to indeks do dowolnej listy struktur z niestandardowymi informacjami. Myślę, że chcesz przechowywać informacje w niewłaściwym miejscu.

Zrozumiem, choć niefortunnie, że w wielu przypadkach właściwe rozwiązanie nie jest właściwym rozwiązaniem. W takim przypadku zdecydowanie zalecam wygenerowanie jakiegoś javascript, aby przechować dodatkowe informacje.

Wiele lat później:

To pytanie zostało zadane mniej więcej trzy lata, zanim data-...atrybuty stały się prawidłową opcją wraz z pojawieniem się HTML 5, więc prawda się zmieniła, a pierwotna odpowiedź, której udzieliłem, nie ma już znaczenia. Teraz sugeruję użycie zamiast tego atrybutów danych .

<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
źródło
jak w takim razie masz przekazać dane do javascript?
nickf