613 Stimmen

Warum findet jQuery oder eine DOM-Methode wie getElementById das Element nicht?

Was sind die möglichen Gründe für document.getElementById , $("#id") oder jede andere DOM-Methode / jQuery-Selektor nicht finden die Elemente?

Beispiele für Probleme sind:

  • jQuery scheitert stillschweigend an der Bindung eines Event-Handlers
  • jQuery "Getter"-Methoden ( .val() , .html() , .text() ) Rückkehr undefined
  • Eine Standard-DOM-Methode, die null was zu einem von mehreren Fehlern führt:

Ungefangener TypeError: Cannot set property '...' of null
Ungefangener TypeError: Eigenschaften von null können nicht gesetzt werden (Einstellung '...')
Ungefangener TypeError: Cannot read property '...' of null
Ungefangener TypeError: Cannot read properties of null (Lesen von '...')

Die gebräuchlichsten Formen sind:

Ungefangener TypeError: Eigenschaft 'onclick' von null kann nicht gesetzt werden
Ungefangener TypeError: Eigenschaft 'addEventListener' von null kann nicht gelesen werden
Ungefangener TypeError: Eigenschaft 'style' von null kann nicht gelesen werden

172voto

Felix Kling Punkte 751464

Kurz und einfach: Weil die gesuchten Elemente (noch) nicht in dem Dokument vorhanden sind.


Für den Rest dieser Antwort werde ich Folgendes verwenden getElementById für Beispiele, aber das Gleiche gilt für getElementsByTagName , querySelector und jede andere DOM-Methode, die Elemente auswählt.

Mögliche Gründe

Es gibt drei Gründe, warum ein Element nicht vorhanden sein könnte:

  1. Ein Element mit der übergebenen ID existiert in dem Dokument nicht wirklich. Sie sollten überprüfen, ob die ID, die Sie an getElementById wirklich mit einer ID eines bestehenden Elements im (generierten) HTML übereinstimmt und dass Sie nicht falsch buchstabiert die ID (IDs sind Groß- und Kleinschreibung !).

    Wenn Sie Folgendes verwenden getElementById sicher sein, dass Sie nur unter Angabe der ID des Elements (z.B., document.getElemntById("the-id") ). Wenn Sie eine Methode verwenden, die einen CSS-Selektor akzeptiert (wie querySelector ), stellen Sie sicher, dass Sie die # vor der ID, um anzuzeigen, dass Sie nach einer ID suchen (z. B., document.querySelector("#the-id") ). Sie müssen no verwenden Sie die # mit getElementById et debe Verwenden Sie es mit querySelector und ähnliches. Beachten Sie auch, dass, wenn die ID Zeichen enthält, die nicht in CSS-Bezeichner (wie zum Beispiel ein . ; id Attribute, die . Zeichen sind eine schlechte Praxis, aber gültig), müssen Sie diese bei der Verwendung von querySelector ( document.querySelector("#the\\.id") )), aber nicht bei der Verwendung von getElementById ( document.getElementById("the.id") ).

  2. Das Element ist nicht vorhanden zur Zeit Sie rufen getElementById .

  3. Das Element ist nicht in dem Dokument, das Sie abfragen, obwohl Sie es auf der Seite sehen können, da es sich in einer iframe (das ein eigenes Dokument ist). Elemente in iframes werden nicht durchsucht, wenn Sie das Dokument durchsuchen, in dem sie enthalten sind.

Wenn das Problem Grund 3 ist (es befindet sich in einem iframe oder ähnliches), müssen Sie das Dokument in der iframe und nicht das übergeordnete Dokument, vielleicht indem man die iframe Element und unter Verwendung seines contentDocument Eigenschaft, um auf sein Dokument zuzugreifen (nur gleiche Herkunft). Der Rest dieser Antwort befasst sich mit den ersten beiden Gründen.

Der zweite Grund - er ist nicht da dennoch - ist durchaus üblich. Die Browser analysieren und verarbeiten den HTML-Code von oben nach unten. Das bedeutet, dass jeder Aufruf eines DOM-Elements, der erfolgt, bevor dieses DOM-Element in der HTML-Datei erscheint, fehlschlägt.

Betrachten Sie das folgende Beispiel:

<script>
    var element = document.getElementById('my_element');
</script>

<div id="my_element"></div>

En div erscheint nachscript . Zu dem Zeitpunkt, zu dem das Skript ausgeführt wird, existiert das Element nicht dennoch y getElementById wird zurückgegeben null .

jQuery

Das Gleiche gilt für alle Selektoren mit jQuery. jQuery findet keine Elemente, wenn Sie falsch buchstabiert Ihr Selektor oder Sie versuchen, sie auszuwählen bevor sie tatsächlich existieren .

Eine zusätzliche Schwierigkeit besteht darin, dass jQuery nicht gefunden wird, weil Sie das Skript ohne Protokoll geladen haben und es vom Dateisystem aus ausführen:

<script src="//somecdn.somewhere.com/jquery.min.js"></script>

diese Syntax wird verwendet, damit das Skript auf einer Seite mit dem Protokoll https:// über HTTPS geladen wird und auf einer Seite mit dem Protokoll http:// die HTTP-Version geladen wird

Es hat den unglücklichen Nebeneffekt, dass der Versuch, die file://somecdn.somewhere.com...


Lösungen

Bevor Sie einen Anruf tätigen bei getElementById (oder jede andere DOM-Methode), vergewissern Sie sich, dass die Elemente, auf die Sie zugreifen möchten, vorhanden sind, d.h. dass das DOM geladen ist.

Dies kann gewährleistet werden, indem Sie einfach Ihr JavaScript nach das entsprechende DOM-Element

<div id="my_element"></div>

<script>
    var element = document.getElementById('my_element');
</script>

In diesem Fall können Sie den Code auch direkt vor dem schließenden Body-Tag ( </body> ) (alle DOM-Elemente sind zum Zeitpunkt der Ausführung des Skripts verfügbar).

Andere Lösungen sind das Anhören der load [MDN] o DOMContentLoaded [MDN] Ereignisse. In diesen Fällen spielt es keine Rolle, wo im Dokument Sie den JavaScript-Code platzieren, Sie müssen nur daran denken, den gesamten DOM-Verarbeitungscode in die Event-Handler zu setzen.

Beispiel:

window.onload = function() {
    // process DOM elements here
};

// or

// does not work IE 8 and below
document.addEventListener('DOMContentLoaded', function() {
    // process DOM elements here
});

Bitte beachten Sie die Artikel auf quirksmode.org für weitere Informationen über Ereignisbehandlung und Browserunterschiede.

jQuery

Stellen Sie zunächst sicher, dass jQuery richtig geladen ist. Verwenden Sie die Entwicklerwerkzeuge des Browsers um herauszufinden, ob die jQuery-Datei gefunden wurde, und korrigieren Sie die URL, falls dies nicht der Fall ist (fügen Sie z. B. die http: o https: Schema am Anfang, Anpassung des Pfades usw.)

Das Zuhören der load / DOMContentLoaded Ereignisse ist genau das, was jQuery mit .ready() [docs] . Ihr gesamter jQuery-Code, der sich auf das DOM-Element auswirkt, sollte sich in diesem Event-Handler befinden.

In der Tat, die jQuery-Anleitung ausdrücklich fest:

Da fast alles, was wir mit jQuery tun, das Document Object Model (DOM) liest oder manipuliert, müssen wir sicherstellen, dass wir mit dem Hinzufügen von Ereignissen usw. beginnen, sobald das DOM bereit ist.

Zu diesem Zweck registrieren wir ein Bereitschaftsereignis für das Dokument.

$(document).ready(function() {
   // do stuff when DOM is ready
});

Alternativ dazu können Sie auch die Kurzsyntax verwenden:

$(function() {
    // do stuff when DOM is ready
});

Beide sind gleichwertig.

20voto

sumit Punkte 1705

Gründe, warum id-basierte Selektoren nicht funktionieren

  1. Das Element/DOM mit der angegebenen id existiert noch nicht.
  2. Das Element existiert, ist aber nicht im DOM registriert [im Falle von HTML-Knoten, die dynamisch aus Ajax-Antworten angefügt werden].
  3. Es gibt mehr als ein Element mit der gleichen ID, was zu einem Konflikt führt.

Lösungen

  1. Versuchen Sie, auf das Element nach seiner Deklaration zuzugreifen, oder verwenden Sie alternativ Dinge wie $(document).ready();

  2. Für Elemente, die aus Ajax-Antworten stammen, verwenden Sie die .bind() Methode von jQuery. Ältere Versionen von jQuery hatten .live() für dasselbe.

  3. Verwenden Sie Tools [z. B. das Webdeveloper-Plugin für Browser], um doppelte IDs zu finden und zu entfernen.

16voto

George Mulligan Punkte 11758

Wenn sich das Element, auf das Sie zugreifen wollen, innerhalb einer iframe und Sie versuchen, darauf außerhalb des Kontexts der iframe wird dies ebenfalls zum Scheitern verurteilt sein.

Wenn Sie ein Element in einem iframe erhalten möchten, können Sie herausfinden, wie aquí .

14voto

Nathan Bubna Punkte 6644

Wie @FelixKling schon sagte, ist das wahrscheinlichste Szenario, dass die von Ihnen gesuchten Knoten (noch) nicht existieren.

Moderne Entwicklungspraktiken können jedoch häufig Dokumentenelemente außerhalb des Dokumentenbaums manipulieren, entweder mit DocumentFragments oder einfach durch direktes Ablösen/Verbinden von aktuellen Elementen. Solche Techniken können als Teil von JavaScript-Templates verwendet werden oder um übermäßige Repaint/Reflow-Operationen zu vermeiden, während die fraglichen Elemente stark verändert werden.

In ähnlicher Weise erlaubt die neue "Shadow DOM"-Funktionalität, die in modernen Browsern eingeführt wird, dass Elemente Teil des Dokuments sind, aber nicht durch document.getElementById und alle seine Geschwistermethoden (querySelector usw.) abgefragt werden können. Dies geschieht, um Funktionen zu kapseln und gezielt zu verbergen.

Aber auch hier ist es sehr wahrscheinlich, dass das gesuchte Element einfach (noch) nicht im Dokument vorhanden ist, und Sie sollten tun, was Felix vorschlägt. Sie sollten sich jedoch auch bewusst sein, dass dies zunehmend nicht der einzige Grund dafür ist, dass ein Element (entweder vorübergehend oder dauerhaft) nicht auffindbar ist.

12voto

CertainPerformance Punkte 306402

Wenn die Reihenfolge der Skriptausführung nicht das Problem ist, kann das Problem auch daran liegen, dass das Element nicht richtig ausgewählt wird:

  • getElementById erfordert, dass die übergebene Zeichenkette die ID ist wortwörtlich und sonst nichts. Wenn Sie der übergebenen Zeichenkette ein Präfix # und die ID beginnt nicht mit einem # , wird nichts ausgewählt:

      <div id="foo"></div>
    
      // Error, selected element will be null:
      document.getElementById('#foo')
      // Fix:
      document.getElementById('foo')
  • Ähnlich verhält es sich bei getElementsByClassName wird der übergebenen Zeichenkette kein Präfix mit einem . :

      <div class="bar"></div>
    
      // Error, selected element will be undefined:
      document.getElementsByClassName('.bar')[0]
      // Fix:
      document.getElementsByClassName('bar')[0]
  • Mit querySelector, querySelectorAll und jQuery, um ein Element mit einem bestimmten Klassennamen zu finden, setzen Sie eine . direkt vor dem Unterricht. Um ein Element mit einer bestimmten ID zu finden, setzen Sie ein # direkt vor der ID:

      <div class="baz"></div>
    
      // Error, selected element will be null:
      document.querySelector('baz')
      $('baz')
      // Fix:
      document.querySelector('.baz')
      $('.baz')

    Die Regeln hier sind in den meisten Fällen identisch mit denen für CSS-Selektoren und können im Detail betrachtet werden aquí .

  • Um ein Element mit zwei oder mehr Attributen (wie zwei Klassennamen oder ein Klassenname und ein data- Attribut), setzen Sie die Selektoren für jedes Attribut nebeneinander in die Selektorzeichenfolge, ohne ein Leerzeichen zwischen ihnen (weil ein Leerzeichen die Nachkommenschaftsselektor ). Zum Beispiel, um zu wählen:

      <div class="foo bar"></div>

    die Abfragezeichenfolge verwenden .foo.bar . Zum Auswählen

      <div class="foo" data-bar="someData"></div>

    die Abfragezeichenfolge verwenden .foo[data-bar="someData"] . Zur Auswahl der <span> unten:

      <div class="parent">
        <span data-username="bob"></span>
      </div>

    verwenden. div.parent > span[data-username="bob"] .

  • Großschreibung und Rechtschreibung spielt eine Rolle für alle oben genannten Punkte. Wenn die Groß- und Kleinschreibung unterschiedlich ist, wird das Element nicht ausgewählt:

      <div class="result"></div>
    
      // Error, selected element will be null:
      document.querySelector('.results')
      $('.Result')
      // Fix:
      document.querySelector('.result')
      $('.result')
  • Sie müssen auch darauf achten, dass die Methoden die richtige Groß- und Kleinschreibung aufweisen. Verwenden Sie eine von:

    $(selector)
    document.querySelector
    document.querySelectorAll
    document.getElementsByClassName
    document.getElementsByTagName
    document.getElementById

    Jede andere Schreibweise oder Großschreibung wird nicht akzeptiert. Zum Beispiel, document.getElementByClassName wird einen Fehler auslösen.

  • Stellen Sie sicher, dass Sie eine Zeichenkette an diese Selektormethoden übergeben. Wenn Sie etwas, das keine Zeichenkette ist, an querySelector , getElementById usw., wird es mit ziemlicher Sicherheit nicht funktionieren.

  • Wenn die HTML-Attribute der Elemente, die Sie auswählen möchten, von Anführungszeichen umgeben sind, müssen es einfache gerade Anführungszeichen sein (entweder einfach oder doppelt); geschweifte Anführungszeichen wie o funktioniert nicht, wenn Sie versuchen, nach ID, Klasse oder Attribut auszuwählen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X