coding_idiot
coding_idiot

Reputation: 13734

Why does the jquery selector ("id,id") selects all elements with duplicate IDs

I came across some year old code written by a good developer (yes, I knew him personally) to access all elements having the same id.

$("#choice,#choice")

It returns all elements having the id. But if we use the below

$("#choice")

It returns only the first match, as expected.

After searching for some time, I'm unable to figure out any official links pointing to his technique, as to how it selected all elements with duplicate id.

Can anyone please explain how is this working ?

UPDATE

Please see the question is not about what alternative to use. I'm aware of classSelectors and attributeSelectors and know having duplicate IDs is not recommended, but sometimes you just have to live with years old code the way it is (if you know what I mean).

http://jsbin.com/zodeyexigo/1/edit?html,js,output

Upvotes: 7

Views: 596

Answers (4)

Dharmesh Patel
Dharmesh Patel

Reputation: 1891

If you look at the code of sizzle.js that jQuery uses for selecting elements based on selector you will understand why this happens. It uses following regex to match simple ID, TAG or class selector:

// Easily-parseable/retrievable ID or TAG or CLASS selectors
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,

but as the selector in question is $("#ID,#ID") it does not match with the selector and uses querySelectorAll (line no 270 in ref link), which replaces selector to "[id='" + nid + "'] " (line no 297 in ref link) which selects all the elements with matching ID.

However, I agree with the other people in this thread, that it is not good idea to have same ID for multiple elements.

Upvotes: 11

Robbie Tapping
Robbie Tapping

Reputation: 2556

So in JS Fiddle i have shown an example of what jQuery is doing.

https://jsfiddle.net/akp3a7La/

When you have a

$('#choice,#choice');

It is actually getting all the instances of the objects #choice twice, and then filtering out any duplicates.

in my example i show you how it does that also when you have something like this

$("#choice,li");

Where

  • items are actually your #choice items.

    In the Jquery Documentation https://api.jquery.com/multiple-selector/

    it talks about multiple Selectors, which is what i think is happening here, your developer friend is selecting the same ID twice, and it would be returning it twice. as you can only have one input with the same ID once on a page (good html syntax)

    Upvotes: -1

  • Aabid
    Aabid

    Reputation: 941

    Having 2 elements with the same ID is not valid html according to the W3C specification.

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

    However, in the other two instances, jQuery relies on the Sizzle selector engine (or querySelectorAll, if available), which apparently selects both elements. Results may vary on a per browser basis.

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

    If you absolutely must select by duplicate ID, use an attribute selector:

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

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

    Note: if possible, you should qualify that selector with a tag selector, like this:

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

    Upvotes: 3

    godblessstrawberry
    godblessstrawberry

    Reputation: 5068

    Having duplicated id on the page making your html not valid . ID is unique identifier for one element on the page (spec). Using classes, that are classify similar elements that's your case and $('.choice') will return set of elements

    Upvotes: -1

    Related Questions