Warum verwenden wir in JavaScript nicht einfach Element-IDs als Bezeichner?

Lesezeit: 9 Minuten

Benutzer-Avatar
GOTO 0

Alle Browser, mit denen ich arbeite, erlauben den Zugriff auf ein Element id="myDiv" indem du einfach schreibst:

myDiv

Siehe hier: http://jsfiddle.net/L91q54Lt/

Wie auch immer, diese Methode scheint ziemlich schlecht dokumentiert zu sein, und tatsächlich erwähnen die Quellen, auf die ich stoße, sie nicht einmal und gehen stattdessen davon aus, dass man sie verwenden würde

document.getElementById("myDiv")

oder vielleicht

document.querySelector("#myDiv")

auf ein DOM-Element zugreifen, auch wenn seine ID im Voraus bekannt ist (dh nicht zur Laufzeit berechnet wird). Ich kann sagen, dass die letzteren Ansätze den Vorteil haben, den Code sicher aufzubewahren, falls jemand versehentlich versucht, ihn neu zu definieren myDiv in einem größeren Umfang (allerdings keine so brillante Idee …), überschreibt es mit einem anderen Wert und fährt fort, ohne den Konflikt zu bemerken.

Aber sonst das? Gibt es Bedenken bei der Verwendung der obigen Kurzform außer dem Codedesign, oder was fehlt mir hier noch?

  • eine Fenstereigenschaft (wie myDiv) kann alles sein (beachten Sie, dass es überschrieben werden kann), aber getElementById gibt das HTMLElement zurück (unabhängig vom Wert der Eigenschaft)

    – Dr.Molle

    15. August 2014 um 11:01 Uhr


  • @Jack: Diese Frage erwähnt nicht den Zugriff auf HTML-Elemente mit IDs über globale Variablen, worum es in dieser Frage geht. Also ich denke nicht, dass „hoch verwandt“ ganz richtig ist.

    – Paul D. Waite

    15. August 2014 um 11:07 Uhr

  • Eng verwandt: stackoverflow.com/questions/3434278/…

    – Qantas 94 Schwer

    15. August 2014 um 11:25 Uhr

  • @ Jack: vielleicht. Ich denke, es wäre mehr Aufwand gewesen, dieses Duplikat zu finden, als die Antwort zu schreiben. Und beachten Sie, dass die doppelte Frage nur das Problem aufwirft, nach dem diese Frage in ihrem allerletzten Satz fragt. Wenn Sie es und seine Antworten lesen, müssen Sie sich durch die anfänglichen Dinge wühlen (wird diese Funktion von allen Browsern unterstützt?), bevor Sie zur Antwort auf diese Frage gelangen (warum ist dies eine schlechte Idee?). „Don’t repeat yourself“ ist ein tolles Prinzip beim Programmieren. Es ist keine universelle Konstante. Duplikation ist nicht immer böse.

    – Paul D. Waite

    15. August 2014 um 12:30 Uhr

  • @Jack: ah, fällige Anerkennung. Die rechtmäßige Beute von „First!“. Ja, es lohnt sich. Aber wenn die Antwort schnell ist, erhält das OP schnell eine Antwort, und wenn es unterschiedliche Formulierungen ähnlicher Fragen gibt, bedeutet dies meiner Meinung nach, dass die Wahrscheinlichkeit größer ist, dass jemand, der dieselbe Frage erneut stellt, eine Übereinstimmung in der automatischen Suche erhält.

    – Paul D. Waite

    15. August 2014 um 12:35 Uhr

Benutzer-Avatar
Juden

Wie auch immer, diese Methode scheint ziemlich schlecht dokumentiert zu sein, und tatsächlich wird sie in den Quellen, auf die ich stoße, nicht einmal erwähnt […]

Abgesehen von der Abhängigkeit von implizit deklarierten globalen Variablen ist der Mangel an Dokumentation ein guter Grund, sie nicht zu verwenden.

Die offensichtliche Förderung von id Werte in globale Variablen ist nicht standardkonform (die HTML5-Spezifikation für das ID-Attribut erwähnt es nicht) und daher sollten Sie nicht davon ausgehen, dass zukünftige Browser es implementieren werden.

EDIT: Es stellt sich dieses Verhalten heraus ist standardkonform – In HTML5, window sollte den Eigenschaftszugriff auf “Benannte Elemente” unterstützen:

Benannte Objekte mit dem Namen name sind für die Zwecke des obigen Algorithmus solche, die entweder:

  • untergeordnete Browserkontexte des aktiven Dokuments, dessen Name lautet Name,
  • a-, applet-, area-, embed-, form-, frameset-, img- oder object-Elemente, die ein name content-Attribut haben, dessen Wert ist Nameoder
  • HTML-Elemente mit einem Ich würde Inhaltsattribut, dessen Wert ist Name.

Quelle: HTML 5-Spezifikation, „Benannter Zugriff auf Fensterobjekt“, Betonung von mir.

Ausgehend davon ist die Einhaltung von Standards kein Grund, dieses Muster zu vermeiden. Die Spezifikation selbst rät jedoch von ihrer Verwendung ab:

Wenn Sie sich darauf verlassen, führt dies in der Regel zu sprödem Code. Welche IDs letztendlich dieser API zugeordnet werden, kann im Laufe der Zeit variieren, wenn beispielsweise neue Funktionen zur Webplattform hinzugefügt werden. Verwenden Sie stattdessen
document.getElementById() oder document.querySelector().

  • Warum sollte die Spezifikation etwas spezifizieren und dann davon abraten, es zu verwenden?! Als ob das Web noch mehr schlechte Praktiken bräuchte. #facepalm#

    – Songo

    15. August 2014 um 14:56 Uhr


  • Ich würde vermuten, um die Unterstützung für Legacy-Muster zu formalisieren, die allgemein (ish) verwendet werden.

    – Juden

    15. August 2014 um 14:59 Uhr

  • so viel ich weiss name != id (notwendigerweise) habe ich nie eine Dokumentation gefunden, die ausdrücklich besagt, dass Sie kein 1-Element mit name=”foo” und ein anderes mit id=”foo” haben können (könnte es übersehen haben), also 1 weitere Ebene der Mehrdeutigkeit. Ich habe den Punkt in Name und ID nicht gesehen – bis die Trennung eine Menge Dinge in der GTK3-API (insbesondere GTKBuilder-XML-UIs) kaputt gemacht hat.

    – Technosaurier

    16. August 2014 um 3:31 Uhr

  • @Izkata Ich weiß, würdest du nicht lieber aus den Fehlern anderer lernen. Ein Großteil des gtkbuilder- und gtk3-Designs wurde nach HTML und CSS modelliert. Als sie dann entschieden, dass Javascript eine erstklassige Sprache zum Erstellen von gtk3-Apps sein würde, änderten sie das alte Verhalten, das name~=id gewesen war, und machten eine Menge Dinge kaputt. Die Möglichkeit, sowohl name als auch id als globale Werte zu referenzieren, ist sehr ähnlich, und ich würde vermuten, dass in einer zukünftigen Ausgabe entweder name ganz wegfällt oder name die globale Behandlung erhält (viele Legacy-Formulare für Nicht-js-Browser hängen davon ab) und id erworben werden müssten (nur Spekulation).

    – Technosaurus

    16. August 2014 um 4:17 Uhr

  • Angesichts der Bearbeitung und des Updates sehe ich keinen Grund, diese Funktion nicht zu verwenden.

    – BSG

    28. August 2017 um 3:05 Uhr

Benutzer-Avatar
Paul D. Waite

Tolle Frage. Wie Einstein wahrscheinlich nicht gesagt hat, sollten die Dinge so einfach wie möglich sein, und nicht einfacher.

Letztere Ansätze haben den Vorteil, dass der Code sicher bleibt, wenn jemand versehentlich versucht, myDiv in einem größeren Umfang neu zu definieren (jedoch keine so brillante Idee …), es mit einem anderen Wert überschreibt und fortfährt, ohne den Konflikt zu bemerken

Das ist der Hauptgrund, warum dies eine schlechte Idee ist, und es ist völlig ausreichend. Auf globale Variablen kann man sich nicht sicher verlassen. Sie können jederzeit von jedem Skript, das auf der Seite ausgeführt wird, überschrieben werden.

Außerdem einfach eintippen myDiv ist keine „Kurzform“ von document.getElementById(). Es ist ein Verweis auf eine globale Variable.document.getElementById() werde gerne wiederkommen null Wenn das Element nicht vorhanden ist, wird beim Versuch, auf eine nicht vorhandene globale Variable zuzugreifen, ein Referenzfehler ausgelöst, sodass Sie Ihre Referenzen auf die globale Variable in einen Try/Catch-Block einschließen müssen, um sicher zu sein.

Dies ist einer der Gründe, warum jQuery so beliebt ist: Wenn Sie es tun $("#myDiv").remove()und es gibt kein Element mit einer ID von myDivwird kein Fehler ausgegeben – der Code wird einfach stillschweigend nichts tun, was oft genau das ist, was Sie bei der DOM-Manipulation wollen.

  • document.getElementById() kehrt zurück null wenn das Element nicht existiert, nicht undefined.

    – GOTO 0

    15. August 2014 um 11:08 Uhr

  • @GOTO0: ooh, Prost Prost, ich wusste, ich hätte das überprüfen sollen.

    – Paul D. Waite

    15. August 2014 um 11:09 Uhr

  • Stilles Scheitern ist ironischerweise auch ein Grund, warum Leute jQuery nicht mögen.

    – Ryan Kinal

    4. Dezember 2014 um 15:54 Uhr

  • @RyanKinal schnell scheitern, billig scheitern. Das sage ich immer.

    – Kapaj

    10. Juli 2015 um 17:05 Uhr

Benutzer-Avatar
Jeremy J Starcher

Es gibt ein paar Gründe:

Sie möchten nicht, dass Ihr Code und Ihr Markup so gekoppelt sind.

Indem Sie einen bestimmten Aufruf verwenden, um auf ein div zuzugreifen, müssen Sie sich keine Sorgen machen, dass der globale Speicherplatz beschädigt wird. Fügen Sie eine Bibliothek hinzu, die deklariert myDiv im globalen Raum und Sie befinden sich in einer Welt voller Schmerzen, die schwer zu beheben sein werden.

Sie können über die ID auf Elemente zugreifen, die nicht Teil des DOM sind

Sie können sich in einem Fragment, einem Frame oder einem Element befinden, das gelöst und noch nicht wieder an das DOM angefügt wurde.

BEARBEITEN: Beispiel für den Zugriff auf nicht angehängte Elemente durch ID

var frag = document.createDocumentFragment();
var span = document.createElement("span");
span.id = "span-test";
frag.appendChild(span);
var span2 = frag.getElementById("span-test");
alert(span === span2);

  • Es sieht so aus, als ob Sie sich irren: Weder Firefox noch Chromium erlauben mir das Zugriffselemente nach ID, die nicht Teil des DOM sind. Zumindest distanzierte.

    – Benutzer

    15. August 2014 um 21:49 Uhr


  • @user Sie können nicht mit darauf zugreifen document.getElementByIdjedoch habe ich meine Antwort aktualisiert, um zu zeigen, wie man auf a zugreift spanvon idinnerhalb von a documentFragment.

    – Jeremy J Starcher

    15. August 2014 um 22:01 Uhr


Benutzer-Avatar
Die Rote Erbse

In meinem Fall hatte ich einen Iframe in meiner Seite. Ich war verwirrt von id Attribut vs name -Attribut, die sich beide auf eine Variable mit dem Namen auswirkten inner_iframezugänglich von window!

  • Wenn ich nur die benutzte id-Attributwie id="inner_iframe", window.inner_iframe ist ein HTMLIFrameElement. Eigenschaften umfassen inner_iframe.contentDocument und inner_iframe.contentWindow wie hier beschrieben*

  • Wenn ich nur die benutzte Namensattributwie name="inner_iframe" dann window.inner_iframe ist ein “Rahmen”, auch bekannt als a “Fensterobjekt”. contentWindowdaher das Namensattribut inner_iframe nicht Eigenschaften haben contentDocument oder contentWindow.

  • Wenn ich verwendet habe beide name und id Attribute, und ich habe beiden Attributen den gleichen Wert gegeben name="inner_iframe" id="inner-iframe"; das name Attribut übertrumpft / verprügelt die id Attribut; Mir blieb das “Fensterobjekt”, nicht das HTMLIFrameElement!

Mein Punkt ist also, mit Mehrdeutigkeiten vorsichtig zu sein; der Konflikt zwischen name und id Attribute für dasselbe Objekt mit zwei verschiedenen APIs: Dies ist nur ein Sonderfall, in dem implizites Verhalten und Anhängen an eine Fenstervariable Sie verwirren können.

*(und nur wenn die <script> wurde nach/unter geladen <iframe> im HTML, oder die <script> gewartet bis window.onload bevor Sie versuchen, über das id-Attribut zuzugreifen)

**Diese Unterscheidung zwischen “Frame” und DOM-Element wird in der Mozilla-Dokumentation wie folgt beschrieben:

Jedes Element im Pseudo-Array window.frames stellt das Fensterobjekt dar, das dem angegebenen Inhalt von ‘s oder ‘ entspricht. nicht das (i)frame DOM-Element (dh window.frames[0] ist dasselbe wie document.getElementsByTagName(“iframe”)[0].contentWindow).

1010630cookie-checkWarum verwenden wir in JavaScript nicht einfach Element-IDs als Bezeichner?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy