Czy wiele różnych elementów HTML może mieć ten sam identyfikator, jeśli są różnymi elementami?


139

Czy taki scenariusz jest ważny ?:

div#foo
span#foo
a#foo

23
Chociaż czasami jest to możliwe, nigdy nie jest ważne.
Paul Creasey,

2
Biorąc pod uwagę wszystko, co zostało powiedziane powyżej, warto zauważyć, że prawdopodobnie natrafi się na wiele takich samych identyfikatorów w dokumencie z treścią utworzoną przez klienta użytkownika (myśl, że ramy, mv *, reaguj, polimer ...). To jeśli ktoś się zastanawiał, dlaczego bardzo profesjonalnie wyglądająca witryna XYZ jest pełna tak złych praktyk kodowania.
Łukasz Matysiak

Odpowiedzi:


180

Nie.

Identyfikatory elementów powinny być unikalne w całym dokumencie.


85
Jakie są konsekwencje, jeśli tego nie zrobisz?
corsiKa

16
@corsiKa konsekwencją jest niezdefiniowane zachowanie, na przykład, co zwraca document.getElementById ("# foo") lub $ ("# foo"), gdy istnieje wiele #foos?
Napotkasz

76
To jest niepoprawne. Całkowicie możliwe jest posiadanie wielu elementów z tym samym identyfikatorem. Na ogół nie jest to najlepsza praktyka , ale ma swoje sporadyczne zastosowania. Wydaje się, że wszyscy cytują, jak działałyby selektory, cóż, jeśli wiesz, że będziesz mieć sprzeczne identyfikatory, używasz selektorów z rodzicem, gdzie identyfikatory pod rodzicem byłyby niepowtarzalne. np . $('div#car span#size)i $('div#truck span#size').
BJury,

18
po co w ogóle używać wielu podobnych identyfikatorów, skoro masz w tym celu klasę?
Max Yari

6
Tak, w praktyce wiele identyfikatorów można zastąpić klasami. Jednak klasy są przeznaczone do stosowania stylów, a nie do identyfikowania elementów, co powoduje, że zakres nazw jest znacznie szerszy, a zatem może się pokrywać. Zwłaszcza jeśli korzystasz z bibliotek innych firm. Id jako „identyfikator” nie ma być mnożone, więc istnieje wyraźna potrzeba umieszczenia czegoś pomiędzy. Praktyczne zastosowanie polega na komponowaniu sekcji strony / domeny w oddzielne jednostki logiczne. W związku z tym wymagane jest użycie (co najmniej) dwuwarstwowej identyfikacji.
Alen Siljak

85

Myślę, że istnieje różnica między tym, czy coś POWINNO być unikalne, czy MUSI być unikalne (tj. Wymuszane przez przeglądarki internetowe).

Czy identyfikatory powinny być unikalne? TAK.

Czy identyfikatory muszą być niepowtarzalne? NIE, przynajmniej IE i FireFox pozwalają wielu elementom mieć ten sam identyfikator.


6
Tak samo działa Chrome (wersja 22 w momencie pisania tego komentarza). : D
omninonsense

27
Zgodnie ze specyfikacją jest to MUSI, a nie POWINIEN. (Czy nadal działa w większości przeglądarek? Tak. Czy to poprawny HTML? Nie. Ponadto, ponieważ getElementByIdw takich przypadkach wynik jest taki undefined, że nie ma sposobu, aby określić, w jaki sposób przeglądarka może sobie z tym poradzić.)
leo

2
@leo jest to jednak prawdziwy świat, w którym przeglądarki nie są w pełni zgodne ze standardami. W tym przypadku może to być dobre rozwiązanie, ponieważ nie ma powodu, aby wymuszać unikalne identyfikatory.
BJury,

1
W HTML5 specyfikacja dla getElementByIdfaktycznie definiuje, że pierwszy element o podanym identyfikatorze musi zostać zwrócony (tak i tak wszystkie przeglądarki obecnie radzą sobie z tą sytuacją) - zobacz moją odpowiedź poniżej, aby uzyskać więcej.
mltsy

1
Nie płacz, użyj jQuery. @leo
Máxima Alekz

67

Czy wiele elementów może mieć ten sam identyfikator?

Tak - niezależnie od tego, czy są to ten sam tag, czy nie, przeglądarki będą renderować stronę, nawet jeśli wiele elementów ma ten sam identyfikator.

Czy to poprawny HTML?

Nie. Jest to nadal aktualne w specyfikacji HTML 5.1 . Jednak specyfikacja mówi również, że getElementById musi zwrócić pierwszy element o podanym identyfikatorze , dzięki czemu zachowanie nie jest niezdefiniowane w przypadku nieprawidłowego dokumentu.

Jakie są konsekwencje tego typu nieprawidłowego kodu HTML?

Większość (jeśli nie wszystkie) przeglądarek wybrałeś i nadal nie wybrać pierwszy element o danym ID, kiedy dzwonisz getElementById. Większość bibliotek, które znajdują elementy według identyfikatora, dziedziczy to zachowanie. Większość (jeśli nie wszystkie) przeglądarek również stosuje style przypisane przez selektory id (np. #myid) Do wszystkich elementów o określonym ID. Jeśli tego oczekujesz i zamierzasz, nie ma żadnych niezamierzonych konsekwencji. Jeśli spodziewasz się / zamierzasz czegoś innego (np. Aby wszystkie elementy z tym identyfikatorem zostały zwrócone lub styl miałby być zastosowany tylko do jednego elementu), twoje oczekiwania nie zostaną spełnione i żadna funkcja oparta na tych oczekiwaniach zawiedzie.

Niektóre biblioteki javascript nie mają oczekiwania, że nie są spełnione, gdy wiele elementy mają ten sam identyfikator (patrz komentarz wootscootinboogie na temat d3.js)

Wniosek

Najlepiej trzymać się standardów, ale jeśli wiesz, że Twój kod działa zgodnie z oczekiwaniami w obecnych środowiskach, a te identyfikatory są używane w przewidywalny / możliwy do utrzymania sposób, są tylko 2 praktyczne powody, aby tego nie robić:

  1. Aby uniknąć ryzyka, że ​​się mylisz, a jedna z używanych bibliotek faktycznie działa nieprawidłowo, gdy wiele elementów ma ten sam identyfikator.
  2. Aby zachować zgodność Twojej witryny / aplikacji z bibliotekami lub usługami (lub programistami!), Które możesz napotkać w przyszłości, które będą działać nieprawidłowo, gdy wiele elementów ma ten sam identyfikator - co jest rozsądną możliwością, ponieważ nie jest to technicznie poprawne HTML.

Moc jest Twoja!


Doskonała odpowiedź. zawsze najlepiej jest trzymać się standardów.
EKanadily

25

Nawet jeśli elementy są różnych typów, może to spowodować poważne problemy ...

Załóżmy, że masz 3 przyciski z tym samym identyfikatorem:

<button id="myid" data-mydata="this is button 1">button 1</button>
<button id="myid" data-mydata="this is button 2">button 2</button>
<button id="myid" data-mydata="this is button 3">button 3</button>

Teraz konfigurujesz jQuerykod, który robi coś po myidkliknięciu przycisków:

$(document).ready(function ()
{
    $("#myid").click(function ()
    {
        var buttonData = $(this).data("mydata");

        // Call interesting function...
        interestingFunction();

        $('form').trigger('submit');
    });
});

Czego byś się spodziewał? Że każdy kliknięty przycisk spowoduje wykonanie konfiguracji obsługi zdarzeń kliknięcia z jQuery. Niestety tak się nie stanie. TYLKO pierwszy przycisk wywołuje moduł obsługi kliknięć. Pozostałe 2 po kliknięciu nic nie robi. To tak, jakby w ogóle nie były guzikami!

Dlatego zawsze przypisuj różne elementy IDsdo HTMLelementów. Dzięki temu będziesz chroniony przed dziwnymi rzeczami. :)

<button id="button1" class="mybtn" data-mydata="this is button 1">button 1</button>
<button id="button2" class="mybtn" data-mydata="this is button 2">button 2</button>
<button id="button3" class="mybtn" data-mydata="this is button 3">button 3</button>

Teraz, jeśli chcesz, aby moduł obsługi zdarzenia kliknięcia działał po kliknięciu dowolnego przycisku, będzie działał idealnie, jeśli zmienisz selektor w kodzie jQuery, aby używał CSSklasy zastosowanej do nich w następujący sposób:

$(document).ready(function ()
{
    $(".mybtn").click(function ()
    {
        var buttonData = $(this).data("mydata");

        // Call interesting function...
        interstingFunction();

        $('form').trigger('submit');
    });
});

co, jeśli mam „#content”, do którego już się odwołałem w zmiennej, i # my-div #content, do której mam tylko przez kilka chwil, po czym usuwam węzeł, do którego się odwołujemy i zapominam o jego zmiennej, po czym # div #content wykonuje polecenie myDiv.outerHTML = myDiv.innerHTML w celu zastąpienia oryginału. Oszczędza to potrzebę kopiowania wszystkich stylów i zawartości #content do #decoy i robienia tego samego. Ma to sens podczas wykonywania przejść.
Dmitry,

Oznacza to, że nawet jeśli użyję 'append', aby dodać wiele elementów o tym samym identyfikatorze, DOM uważa tylko pierwszy element za rzeczywisty, najlepiej 1 ID = 1 element
Karan Kaw

22

Nie. Dwa elementy o tym samym identyfikatorze są nieprawidłowe. Identyfikatory są unikalne, jeśli chcesz zrobić coś takiego, użyj klasy. Nie zapominaj, że elementy mogą mieć wiele klas, używając spacji jako separatora:

<div class="myclass sexy"></div>

12

Oficjalna specyfikacja HTML mówi, że tagi id muszą być unikalne ORAZ oficjalna specyfikacja stwierdza również, że jeśli renderowanie może zostać ukończone, musi (tj. Nie ma czegoś takiego jak „błędy” w HTML, tylko „nieprawidłowy” HTML). Oto jak tagi identyfikacyjne faktycznie działają w praktyce . Wszystkie są nieważne , ale nadal działają:

To:

<div id="unique">One</div>
<div id="unique">Two</div>

Renderuje dobrze we wszystkich przeglądarkach. Jednak document.getElementById zwraca tylko obiekt, a nie tablicę; będziesz mógł wybrać tylko pierwszy element div za pomocą identyfikatora. Gdybyś miał zmienić id pierwszego div za pomocą JavaScript, drugi identyfikator byłby wtedy dostępny za pomocą document.getElementById (testowane na Chrome, FireFox i IE11). Nadal możesz wybrać element div za pomocą innych metod wyboru, a jego właściwość id zostanie zwrócona poprawnie.

Należy pamiętać, że powyższy problem otwiera potencjalną lukę w zabezpieczeniach witryn, które renderują obrazy SVG, ponieważ pliki SVG mogą zawierać elementy DOM, a także tagi identyfikacyjne (umożliwia przekierowanie skryptów DOM przez przesłane obrazy). Dopóki plik SVG jest umieszczony w DOM przed elementem, który zastępuje, obraz otrzyma wszystkie zdarzenia JavaScript przeznaczone dla innego elementu.

O ile wiem, ten problem nie jest obecnie widoczny dla nikogo na radarze, ale jest prawdziwy.

To:

<div id="unique" id="unique-also">One</div>

Również renderuje się dobrze we wszystkich przeglądarkach. Jednak tylko pierwszy identyfikator zdefiniowany w ten sposób jest używany, jeśli próbowałeś document.getElementById ('unique-also'); w powyższym przykładzie zwracane byłoby null (testowane na Chrome, FireFox i IE11).

To:

<div id="unique unique-two">Two</div>

Również renderuje się dobrze we wszystkich przeglądarkach, jednak w przeciwieństwie do tagów klas, które mogą być oddzielone spacją, znacznik id dopuszcza spacje, więc identyfikator powyższego elementu jest w rzeczywistości „unique unique-two” i pyta dom o „unique” lub „unique-two” oddzielnie zwraca wartość null, chyba że zdefiniowano inaczej w innym miejscu DOM (testowane w Chrome, FireFox i IE11).


1
„tag id dopuszcza spacje” - chociaż zgodnie ze specyfikacją „wartość nie może zawierać żadnych znaków spacji”.
MrWhite

Zgadzam się. Jest jednak specyfikacja i sposób działania przeglądarek. Przeglądarki historycznie traktują specyfikację jako cel, ale nie były rygorystyczne w przypadku wielu elementów. Myślę, że robią to, ponieważ gdyby spełnili specyfikację, zepsułoby to wiele istniejących witryn lub coś w tym stylu. Wspomnę na górze, że chociaż te rzeczy działają, są nieważne.
Nick Steele

5

Odpowiedź SLaks jest poprawna, ale jako dodatek zauważ, że specyfikacje x / html określają, że wszystkie identyfikatory muszą być unikalne w (pojedynczym) dokumencie html . Chociaż nie jest to dokładnie to, o co prosił operator, mogą istnieć ważne przypadki, w których ten sam identyfikator jest dołączony do różnych jednostek na wielu stronach.

Przykład:

(serwowane w nowoczesnych przeglądarkach) article # main-content { styled one way }
(provided to legacy) div # main-content { styled inaczej }

Prawdopodobnie jest to jednak anty-wzór. Po prostu wychodzę tutaj jako adwokat diabła.


1
Słuszna uwaga. Chociaż dynamicznie generowana treść, która ma zostać wstawiona na inną stronę, powinna całkowicie unikać identyfikatorów. Identyfikatory są jak globale w językach programowania, możesz ich używać i są ważne przypadki, w których jest to fajny hack, który upraszcza wszystko. Warto zastanowić się nad zrobieniem rzeczy przed włamaniem.
psycho brm

4

I choć warto, w Chrome 26.0.1410.65, Firefox 19.0.2 i przynajmniej Safari 6.0.3, jeśli masz wiele elementów z tym samym identyfikatorem, selektory jquery (przynajmniej) zwrócą pierwszy element z tym identyfikatorem.

na przykład

<div id="one">first text for one</div>
<div id="one">second text for one</div>

i

alert($('#one').size());

Zobacz http://jsfiddle.net/RuysX/ dla testu.


Chyba że używasz bardziej złożonego selektora, takiego jak div#oneTo, oczywiście, nie zmienia to faktu, że jest nieprawidłowy.
Kevin B

Być może ta odpowiedź jest prawdziwa, mówię to z doświadczenia.
Dibyanshu Jaiswal

4

Cóż, używając walidatora HTML na w3.org , specyficznego dla HTML5, identyfikatory muszą być unikalne

Rozważ następujące...

<!DOCTYPE html> 
<html>
    <head>
        <meta charset="UTF-8">
        <title>MyTitle</title> 
    </head>
    <body>
        <div id="x">Barry</div>
        <div id="x">was</div>
        <div id="x">here</div>
    </body>
</html>

walidator odpowiada ...

Line 9, Column 14: Duplicate ID x.      <div id="x">was</div>
Warning Line 8, Column 14: The first occurrence of ID x was here.       <div id="x">Barry</div>
Error Line 10, Column 14: Duplicate ID x.       <div id="x">here</div>
Warning Line 8, Column 14: The first occurrence of ID x was here.       <div id="x">Barry</div>

... ale OP wyraźnie określił - co z różnymi typami elementów. Rozważ więc następujący HTML ...

<!DOCTYPE html> 
<html>
    <head>
        <meta charset="UTF-8">
        <title>MyTitle</title> 
    </head>
    <body>
        <div id="x">barry
            <span id="x">was here</span>
        </div>
    </body>
</html>

... wynik z walidatora to ...

Line 9, Column 16: Duplicate ID x.          <span id="x">was here</span>
Warning Line 8, Column 14: The first occurrence of ID x was here.       <div id="x">barry

Wniosek:

W obu przypadkach (ten sam typ elementu lub inny typ elementu), jeśli identyfikator zostanie użyty więcej niż raz, nie zostanie uznany za prawidłowy HTML5.


2

Możemy użyć nazwy klasy zamiast id. html id powinny być unikalne, ale klasy nie. podczas pobierania danych przy użyciu nazwy klasy może zmniejszyć liczbę linii kodu w plikach js.

$(document).ready(function ()
{
    $(".class_name").click(function ()
    {
        //code
    });
});


1

Myślę, że nie możesz tego zrobić, ponieważ Id jest wyjątkowy, musisz go użyć dla jednego elementu. Możesz użyć klasy do tego celu


1

<div id="one">first text for one</div>
<div id="one">second text for one</div>

var ids = document.getElementById('one');

identyfikatory zawierają tylko pierwszy element div. Więc nawet jeśli istnieje wiele elementów o tym samym identyfikatorze, obiekt dokumentu zwróci tylko pierwsze dopasowanie.


0

Nie, identyfikatory muszą być niepowtarzalne. W tym celu możesz użyć klas

<div class="a" /><div class="a b" /><span class="a" />

div.a {font: ...;}
/* or just: */
.a {prop: value;}

0

Czy można mieć więcej niż jednego ucznia w klasie z tym samym numerem Roll / Id? W idatrybucie HTML jest tak. Możesz użyć dla nich tej samej klasy. na przykład:

<div class="a b c"></div>
<div class="a b c d"></div>

I tak dalej.


0

Zwykle lepiej nie używać wielokrotnie tego samego identyfikatora na stronie html. Mimo to możliwe jest wielokrotne użycie tego samego identyfikatora na stronie. Jednak gdy używasz identyfikatora jako części URI / adresu URL, jak poniżej:

https://en.wikipedia.org/wiki/FIFA_World_Cup#2015_FIFA_corruption_case

A jeśli identyfikator („2015_FIFA_corruption_case”) jest używany tylko dla jednego (span) elementu na stronie internetowej:

<span class="mw-headline" id="2015_FIFA_corruption_case">2015 FIFA corruption case</span>

Nie byłoby problemu. Wręcz przeciwnie, ten sam identyfikator istnieje w więcej niż jednym miejscu, przeglądarka byłaby zdezorientowana.


0

Tak, moga.

Nie wiem, czy wszystkie te odpowiedzi są nieaktualne, ale po prostu otwórz youtube i sprawdź html. Spróbuj przejrzeć sugerowane filmy, zobaczysz, że wszystkie mają ten sam identyfikator i powtarzalną strukturę w następujący sposób:

<span id="video-title" class="style-scope ytd-compact-radio-renderer" title="Mix - LARA TACTICAL">
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.