it-swarm.dev

Zwei HTML-Elemente mit demselben ID-Attribut: Wie schlimm ist es wirklich?

Durchsuchen Sie einfach den Quellcode von Google Maps. In ihrem Header haben sie 2 Divs mit id = "search", einer enthält den anderen und hat auch das Attribut jstrack = "1". Es gibt eine Form, die sie so trennt:

<div id="search" jstrack="1">
    <form action="/maps" id="...rest isn't important">
        ...
        <div id="search">...

Da dies Google ist, gehe ich davon aus, dass es kein Fehler ist.

Wie schlimm kann es also sein, gegen diese Regel zu verstoßen? Warum sollten Sie IDs wie Klassen nicht wiederverwenden, solange Sie bei der Auswahl von CSS und Dom vorsichtig sind? Tut jemand dies absichtlich und wenn ja, warum?

128
danludwig

Spezifikation sagt EINZIGARTIG

HTML 4.01-Spezifikation besagt, dass die ID dokumentweit eindeutig sein muss.

HTML 5-Spezifikation sagt dasselbe, aber mit anderen Worten. Es heißt, dass ID in seinem Home-Teilbaum eindeutig sein muss, was im Grunde das Dokument ist, wenn wir lesen Sie die Definition davon .

Vermeide Dopplungen

Da HTML-Renderer beim HTML-Rendering jedoch sehr nachsichtig sind, lassen sie doppelte IDs zu. Dies sollte nach Möglichkeit vermieden und strikt vermieden werden , wenn programmgesteuert auf Elemente über IDs in JavaScript zugegriffen wird. Ich bin nicht sicher, welche getElementById -Funktion zurückgegeben werden soll, wenn mehrere übereinstimmende Elemente gefunden werden. Sollte es:

  • fehler zurückgeben?
  • erstes passendes Element zurückgeben?
  • letztes übereinstimmendes Element zurückgeben?
  • eine Reihe von übereinstimmenden Elementen zurückgeben?
  • nichts zurückgeben?

Aber selbst wenn Browser heutzutage zuverlässig funktionieren, kann niemand dieses Verhalten in Zukunft garantieren, da dies gegen die Spezifikation verstößt. Aus diesem Grund empfehle ich Ihnen , niemals IDs innerhalb desselben Dokuments zu duplizieren.

146
Robert Koritnik

Sie fragten "wie schlimm". Also, um die (völlig genaue) Antwort von RobertKoritnik ein wenig zu präzisieren ...

Dieser Code ist falsch. Falsch kommt nicht in Graustufen. Dieser Code verstößt gegen den Standard und ist daher falsch. Die Validierungsprüfung würde fehlschlagen, und das sollte auch so sein.

Allerdings würde sich derzeit kein Browser auf dem Markt darüber beschweren oder überhaupt ein Problem damit haben. Browser wären in ihrem Recht sich darüber zu beschweren, aber keine der aktuellen Versionen von ihnen tut dies derzeit. Dies bedeutet nicht, dass zukünftige Versionen diesen Code möglicherweise nicht schlecht behandeln.

Ihr Verhalten beim Versuch, diese ID als Selektor zu verwenden, entweder in CSS oder Javascript, ist nicht zu erraten und variiert wahrscheinlich von Browser zu Browser. Ich nehme an, es könnte eine Studie durchgeführt werden, um zu sehen, wie jeder Browser darauf reagiert. Ich denke, im besten Fall würde es wie "class =" behandelt und die Liste von ihnen ausgewählt. (Das könnte JavaScript-Bibliotheken jedoch verwirren. Wenn ich der Autor von jQuery wäre, hätte ich möglicherweise meinen Auswahlcode so optimiert, dass ich, wenn Sie mit einem Selektor zu mir kommen, der mit "#" beginnt, ein einzelnes Objekt erwarte und ein bekomme Liste könnte mich komplett borken.)

Es kann auch die erste oder möglicherweise die letzte auswählen oder keine davon auswählen oder den Browser vollständig zum Absturz bringen. Keine Möglichkeit zu sagen, ohne es zu versuchen.

"Wie schlecht" hängt dann ganz davon ab, wie streng ein bestimmter Browser die HTML-Spezifikation implementiert und was er tut, wenn er mit einer Verletzung dieser Spezifikation konfrontiert wird.

EDIT: Ich bin heute gerade darauf gestoßen. Ich ziehe verschiedene Komponenten aus Suchformularen für verschiedene Arten von Entitäten ein, um ein großartiges All-in-One-Berichtsdienstprogramm für diese Site zu erstellen. Ich lade die Suchformulare der Remote-Seiten in versteckte Divs und stecke sie in meine Berichtsgenerator, wenn der entsprechende Entitätstyp als Quelle für den Bericht ausgewählt ist. Es gibt also eine versteckte Version des Formulars und eine Version, die im Berichtsgenerator angezeigt wird. Das mitgelieferte JavaScript bezieht sich in allen Fällen auf Elemente nach ID, von denen sich jetzt ZWEI auf der Seite befinden - das versteckte und das angezeigte.

Was jQuery zu tun scheint, ist, mich als ERSTEN auszuwählen, was in allen Fällen genau der ist, den ich NICHT will.

Ich arbeite daran, indem ich Selektoren schreibe, um den Bereich der Seite anzugeben, in den ich mein Feld einfügen möchte (dh: $ ('# containerDiv #specificElement')). Es gibt jedoch eine Antwort auf Ihre Frage: jQuery on Chrome verhält sich definitiv besonders, wenn Sie mit dieser Spezifikationsverletzung konfrontiert werden.

31
Dan Ray

Wie schlimm ist es wirklich?

  1. Das bringt mich zum Weinen
  2. Es ist ungültig
  3. Viele Javascript-Bibliotheken funktionieren nicht wie erwartet
  4. Es macht Ihren Code verwirrend

Erfahrungsgemäß gibt getElementById in den wichtigsten Browsern das erste übereinstimmende Element im Dokument zurück. Dies ist jedoch in Zukunft möglicherweise nicht immer der Fall.

Wenn jQuery eine ID erhält, z. B. #foo, verwendet es getElementById und ahmt dieses Verhalten nach. Wenn Sie dies umgehen müssen (das ist traurig), können Sie $ ("* # foo") verwenden, um jQuery davon zu überzeugen, getElementsByTagName zu verwenden und eine Liste aller übereinstimmenden Elemente zurückzugeben.

Ich muss oft Code für andere Sites schreiben und das umgehen. In einer gerechten Welt müsste ich keine Funktionen neu entwerfen, um zunächst zu überprüfen, ob eine ID eindeutig ist. IDs sollten immer eindeutig sein. Die Welt ist grausam und deshalb weine ich.

22
ColBeseder

Sie können sehr viele Dinge tun - aber das bedeutet nicht, dass Sie sollten.

Als Programmierer (im Allgemeinen) bauen wir unser Leben darauf auf, präzise zu sein und die Regeln zu befolgen - hier ist eine Regel, die einfach zu befolgen ist und die für das, was wir tun, ziemlich grundlegend ist - wir mögen (abhängig von ) eindeutige Kennungen innerhalb eines bestimmten Bereichs ...

Die Regel zu brechen ist etwas, was wir tun können, weil der Browser viel zu entgegenkommend ist - aber wirklich, wir wären alle besser dran, wenn die Browser streng darauf bedacht wären, wohlgeformtes und gültiges HTML zu benötigen, hätte der geringe Schmerz, den es verursacht hätte, längst zugenommen wurde zurückgezahlt!

Also, ist es wirklich so schlimm? Wie können Sie als Programmierer überhaupt fragen? Es ist ein Verbrechen gegen die Zivilisation (-:


Nachtrag:

Sie schreiben, dass Browser zu entgegenkommend sind, als wäre es eine schlechte Sache

Ich mache das, weil es so ist - wir reden nicht über komplizierte Regeln, wir reden im Wesentlichen darüber, Dinge gut zu formen und auf andere Weise Regeln anzuwenden, die mechanisch getestet werden können und die es wiederum einfacher machen, das Ergebnis mechanisch zu verarbeiten. Wenn die Browser streng gewesen wären, hätten sich die Tools sehr schnell angepasst, um dies zu unterstützen - es war nicht so, dass sie es nicht taten, einige in dem Maße, in dem sie diesen Fehler stattdessen ausnutzen. Denken Sie nur daran - E-Mail wäre ein viel schöneres Medium gewesen, wenn MS und Netscape es nicht vermasselt hätten, uneingeschränktes HTML zuzulassen, wenn eine weitaus weniger komplexe "E-Mail-Markup-Sprache" mit expliziter Unterstützung für zitierten Text uns ein weitaus besseres Werkzeug gegeben hätte ... aber dieses Schiff segelte und in ähnlicher Weise können wir die Stalltür nicht schließen, was Browser erlauben (wir sollten, HTML5 sollten haben), aber wir können nicht

8
Murph

In Scripting: getElementByID gibt nur die erste Übereinstimmung zurück. In CSS: #id wirkt sich auf ALLE Elemente mit dieser ID aus. Im Browser hat das Rendern keine Auswirkungen.

Dies ist das Verhalten des w3c-Standards. Keine mögliche, es ist die faktisch definierte.

https://dom.spec.whatwg.org/#interface-nonelementparentnode

7
Bart Calixto