Wie funktioniert jQuery, wenn mehrere Elemente mit der gleichen “ID” vorhanden sind?

Ich hole Daten von der Google AdWords-Website, die mehrere Elemente mit derselben id .

Könnten Sie bitte erklären, warum die folgenden 3 Abfragen nicht mit der gleichen Antwort (2) resultieren?

Live-Demo

HTML:

 
1 2 3

JS:

 $(function() { var w = $("div"); console.log($("#a").length); // 1 - Why? console.log($("body #a").length); // 2 console.log($("#a", w).length); // 2 }); 

Das Vorhandensein von 2 Elementen mit derselben ID ist laut der W3C-Spezifikation kein gültiger HTML-Code.

Wenn Ihr CSS-Selektor nur über einen ID-Selektor verfügt (und nicht in einem bestimmten Kontext verwendet wird), verwendet jQuery die native Methode document.getElementById , die nur das erste Element mit dieser ID zurückgibt.

In den anderen beiden Fällen stützt sich jQuery jedoch auf die Sizzle-Selektor-Engine (oder querySelectorAll , falls verfügbar), die beide Elemente scheinbar auswählt. Die Ergebnisse können je nach Browser variieren.

Sie sollten jedoch niemals zwei Elemente auf derselben Seite mit derselben ID haben. Wenn Sie es für Ihr CSS benötigen, verwenden Sie stattdessen eine class.


Wenn Sie unbedingt eine doppelte ID auswählen müssen, verwenden Sie einen Attributselektor:

 $('[id="a"]'); 

Werfen Sie einen Blick auf die Geige: http://jsfiddle.net/P2j3f/2/

Hinweis: Wenn möglich, sollten Sie diesen Selektor mit einem Tag-Selektor wie folgt qualifizieren:

 $('span[id="a"]'); 

Es sollte nur ein Element mit einer bestimmten ID geben. Wenn Sie in dieser Situation stecken bleiben, finden Sie in der zweiten Hälfte meiner Antwort Optionen.

Wie sich ein Browser verhält, wenn Sie mehrere Elemente mit derselben ID haben (illegales HTML), ist nicht durch die Spezifikation definiert. Sie können alle Browser testen und herausfinden, wie sie sich verhalten, aber es ist unklug, diese Konfiguration zu verwenden oder sich auf ein bestimmtes Verhalten zu verlassen.

Verwenden Sie classn, wenn mehrere Objekte denselben Bezeichner haben sollen.

 
1 2 3
$(function() { var w = $("div"); console.log($(".a").length); // 2 console.log($("body .a").length); // 2 console.log($(".a", w).length); // 2 });

Wenn Sie Elemente mit identischen IDs zuverlässig betrachten möchten, weil Sie das Dokument nicht reparieren können, müssen Sie eine eigene Iteration durchführen, da Sie sich nicht auf eine der integrierten DOM-functionen verlassen können.

Du könntest das so machen:

 function findMultiID(id) { var results = []; var children = $("div").get(0).children; for (var i = 0; i < children.length; i++) { if (children[i].id == id) { results.push(children[i]); } } return(results); } 

Oder mit jQuery:

 $("div *").filter(function() {return(this.id == "a");}); 

jQuery Arbeitsbeispiel: http://jsfiddle.net/jfriend00/XY2tX/ .

Warum Sie unterschiedliche Ergebnisse erhalten, hätte das mit der internen Implementierung von Code zu tun, der die eigentliche Selektoroperation ausführt. In jQuery können Sie den Code untersuchen, um herauszufinden, was eine bestimmte Version tut, aber da dies illegales HTML ist, gibt es keine Garantie, dass es im Laufe der Zeit gleich bleibt. Von dem, was ich in jQuery gesehen habe, überprüft es zunächst, ob der Selektor eine einfache ID wie #a und wenn ja, hat er document.getElementById("a") . Wenn der Selektor komplexer ist und querySelectorAll() existiert, querySelectorAll() jQuery den Selektor oft an die eingebaute Browserfunktion, die eine für diesen Browser spezifische Implementierung aufweist. Wenn querySelectorAll() nicht vorhanden ist, verwendet es die Sizzle-Selektor-Engine, um manuell den Selektor zu finden, der über eine eigene Implementierung verfügt. So können Sie mindestens drei verschiedene Implementierungen alle in der gleichen Browser-Familie abhängig von der genauen Auswahl und wie neu der Browser ist. Dann haben einzelne Browser ihre eigenen querySelectorAll() Implementierungen. Wenn Sie mit dieser Situation zuverlässig umgehen wollen, müssen Sie wahrscheinlich Ihren eigenen Iterationscode verwenden, wie ich oben gezeigt habe.

Der id Selektor von jQuery gibt nur ein Ergebnis zurück. Der descendant und multiple Selektoren in der zweiten und dritten statement sind so gestaltet, dass sie mehrere Elemente auswählen. Es ist ähnlich zu:

Erklärung 1

 var length = document.getElementById('a').length; 

… liefert ein Ergebnis.

Aussage 2

 var length = 0; for (i=0; i 

... liefert zwei Ergebnisse.

Aussage 3

 var length = document.getElementById('a').length + document.getElementsByTagName('div').length; 

... liefert auch zwei Ergebnisse.

Auf der Seite ID Selector jQuery :

Jeder ID-Wert muss nur einmal in einem Dokument verwendet werden. Wenn mehreren Elementen dieselbe ID zugewiesen wurde, wird bei Abfragen, die diese ID verwenden, nur das erste übereinstimmende Element im DOM ausgewählt. Auf dieses Verhalten sollte man sich jedoch nicht verlassen; Ein Dokument mit mehr als einem Element mit derselben ID ist ungültig.

Freches Google. Aber sie schließen nicht einmal ihre und Tags, die ich höre. Die Frage ist jedoch, warum Misha’s 2. und 3. Anfragen 2 und nicht 1 zurückgeben.

Wenn Sie mehrere Elemente mit derselben ID oder demselben Namen haben, weisen Sie diesen mehreren Elementen dieselbe class zu und greifen Sie über den Index darauf zu, und führen Sie die erforderliche Operation aus.

  
1 2 3

JQ:

 $($(".demo")[0]).val("First span"); $($(".demo")[1]).val("Second span"); 

Sie können einfach $ (‘span # a’) eingeben, um die Länge zu erhalten.

Hier ist die Lösung für Ihren Code:

 console.log($('span#a').length); 

Versuchen Sie JSfiddle: https://jsfiddle.net/vickyfor2007/wcc0ab5g/2/