How does jQuery work when there are several elements with the same "id"?

I am retrieving data from a Google AdWords website with multiple elements with the same id .

Could you explain why the following 3 queries do not match the same answer (2)?

Live demo

HTML:

 <div> <span id="a">1</span> <span id="a">2</span> <span>3</span> </div> 

JS:

 $(function() { var w = $("div"); console.log($("#a").length); // 1 - Why? console.log($("body #a").length); // 2 console.log($("#a", w).length); // 2 }); 
+48
jquery
Dec 14 2018-11-11T00:
source share
6 answers

The presence of two elements with the same identifier is invalid html in accordance with the W3C specification.

When your CSS selector has only an identifier selector (and is not used in a specific context), jQuery uses its own document.getElementById method, which returns only the first element with that identifier.

However, in two other cases, jQuery relies on the Sizzle selector (or querySelectorAll , if available), which seems to select both. Results may vary for each browser.

However, you should never have two elements on the same page with the same identifier. If you need it for your CSS, use a class instead.




If you absolutely must choose a duplicate ID, use the attribute selector:

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

Take a look at the fiddle: http://jsfiddle.net/P2j3f/2/

Note: if possible, you should qualify this selector with a tag selector, for example:

 $('span[id="a"]'); 
+61
Dec 14 '11 at 1:40
source share
β€” -

There should be only one element with the given identifier. If you are stuck in this situation, see the second half of my answer for options.

How the browser works when you have several elements with the same identifier (illegal HTML) is not determined by the specification. You can check all browsers and find out how they behave, but it is unwise to use this configuration or rely on any specific behavior.

Use classes if you want multiple objects to have the same identifier.

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

If you want to look reliably at elements with identifiers that are the same because you cannot fix the document, then you will have to do your own iteration, since you cannot rely on any of the built-in DOM functions.

You can do it as follows:

 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); } 

Or using jQuery:

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

JQuery working example: http://jsfiddle.net/jfriend00/XY2tX/ .

As for why you get different results, this is due to the internal implementation of any part of the code that performs the actual selection operation. In jQuery, you can examine the code to find out what a given version does, but since it is illegal HTML, there is no guarantee that it will remain unchanged over time. From what I saw in jQuery, it first checks to see if the selector is a simple id like #a , and if so, just use document.getElementById("a") . If the selector is more complex than the one, and querySelectorAll() exists, jQuery often passes the selector to a browser built-in function that will have an implementation specific to that browser. If querySelectorAll() does not exist, then it will use the Sizzle selection mechanism to manually find a selector that will have its own implementation. Thus, you can have at least three different implementations in the same browser family, depending on the exact selector and how the new browser is. Then, individual browsers will have their own querySelectorAll() implementations. If you want to deal with this situation reliably, you probably have to use your own iterative code, as shown above.

+3
Dec 14 2018-11-11T00:
source share
Selector

jQuery id returns only one result. The descendant and multiple selectors in the second and third statements are for selecting multiple items. It looks like:

Statement 1

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

... Gets one result.

Statement 2

 var length = 0; for (i=0; i<document.body.childNodes.length; i++) { if (document.body.childNodes.item(i).id == 'a') { length++; } } 

... Gets two results.

Statement 3

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

... also gives two results.

+2
Dec 14 2018-11-11T00:
source share

On the id Selector jQuery page:

Each id value should be used only once in the document. If multiple elements have been assigned the same identifier, queries that use this identifier will select only the first matched element in the DOM. However, this behavior cannot be relied upon; A document with more than one element using the same identifier is invalid.

Naughty google. But they don’t even close the <html> and <body> tags that I hear. The question is why Misha 2nd and 3rd queries return 2, not 1.

+2
Dec 14 2018-11-11T00:
source share

If you have several elements with the same identifier or the same name, just assign one class to these elements and access them by index and perform the required operation.

  <div> <span id="a" class="demo">1</span> <span id="a" class="demo">2</span> <span>3</span> </div> 

JQ:

 $($(".demo")[0]).val("First span"); $($(".demo")[1]).val("Second span"); 
0
Nov 27 '15 at 12:52
source share

you can just write $ ('span # a'). length to get the length.

Here is the solution for your code:

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

try JSfiddle: https://jsfiddle.net/vickyfor2007/wcc0ab5g/2/

0
May 03 '16 at 5:28
source share



All Articles