9

Can someone shed some light on the behavior of javascript getElementById() when there are elements with duplicate IDs in HTML DOM??

Arjun
  • 6,501
  • 10
  • 32
  • 34

5 Answers5

13

While there is no standard behavior defined, typically it will return the first element found.

Demo: http://jsfiddle.net/ruNKK/

Ayman Safadi
  • 11,502
  • 1
  • 27
  • 41
  • Thanks Ayman, Is there any way to list all elements with specified id? – Arjun Jul 17 '12 at 18:41
  • 1
    Out of curiosity, is this behavior defined in the spec? Or is it unspecified, but most (if not all) browsers behave like this? – Ortiga Jul 17 '12 at 18:42
  • it is defined. you have to use unique IDs, though you can use name for multiple elements and in return you can get array of elements – Raab Jul 17 '12 at 18:46
  • 1
    Someone (couldn't see who, posted this link then deleted this post: http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-getElBId ). Whoever it is, thanks... – Ortiga Jul 17 '12 at 18:47
  • 1
    Like @RabNawaz said, IDs **must** be unique. You can have multiple elements with the same `name` and `class` attributes. – Ayman Safadi Jul 17 '12 at 18:48
  • @Arjun, you're looking for something like `document.getElementsByAttribute`, which believe or not, doesn't exist! Based on [Dustin Diaz's own implementation](http://snipplr.com/view.php?codeview&id=28115), check out this updated demo: http://jsfiddle.net/ruNKK/1/. – Ayman Safadi Jul 17 '12 at 18:49
  • @RabNawaz: no, it's undefined. One could implement getElementById returning an array of all elements with same Id, and yet it be conformant to W3 specs. – Ortiga Jul 17 '12 at 18:50
  • @Andre It is defined that the function should only return an `Element` or `null`, so defining it to return a `NodeList` (or `Array`) isn't supported by the spec. Now, whether it returns the *first* or *last* match is undefined, but most (if not all) implementations will return the first. – Jonathan Lonowski Jul 17 '12 at 18:53
  • The answer is not correct as is. If multiple elements have the same ID, then it is not specified which of the elements gets returned. *"Behavior is not defined if more than one element has this id."* http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html – Felix Kling Jul 17 '12 at 19:14
  • @FelixKling While it may not be technically defined, in my experience, that is the typical behavior across multiple browsers. – Ayman Safadi Jul 17 '12 at 20:03
  • 1
    The point is that you can't rely on the behaviour, even if all current implementations does it the same way. Browser vendors always tries to make a better browser, so it's not so unlikely that any new browser will try to do it differently. – Guffa Jul 17 '12 at 20:46
13

If you have multiple elements with the same id, you can select them all with

document.querySelectorAll("[id='myid']")

However, if you are in control of it you should just fix the HTML.

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
Esailija
  • 138,174
  • 23
  • 272
  • 326
8

Yes, the behaviour is undefined.

The markup is invalid, and there is no standard that defines what the browser should do in that situation.

Each browser will try to do something reasonable, usually return the first element. Other possible ways that it could be handled would be to return the last element, no element at all (null), or throw an error.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • If anyone has actually posted test results of how various browsers deal with this, I haven't been able to find it. Hypothetically, if ~all browsers handle it consistently, then it wouldn't be the first time we had a strong basis for a new standard, or at least a de facto standard we can all work with. It has always annoyed me that IDs are "required" to be unique, but not guaranteed, enforced, or even any warning or error thrown when it happens. Barring the sudden appearance of the latter, I might suggest we can dispense with the former. – wwwmarty Sep 24 '14 at 12:37
4

It is illegal to have multiple objects with the same ID. Because it is not supposed to be allowed, the behavior of getElementById() with multiple matches present is not specified in the spec. In fact, the spec explicitly says: "Behavior is not defined if more than one element has this ID.".

In the few browsers I've tried this in, it returns the first one, but obviously you should not rely on that.

If you want to find all matches, you would have to design a query that looks at the IDs of all tags and collects the ones that match yours.

In plain javascript, you could do it like this:

function getAllElementsById(id) {
    var all = document.getElementsByTagName("*");
    var results = [], elem;
    for (var i = 0; i < all.length; i++) {
        elem = all[i];
        if (elem.id && elem.id === id) {
            results.push(elem);
        }
    }
    return(results);
}
jfriend00
  • 683,504
  • 96
  • 985
  • 979
1

yes.It will return to the first one.We can not use same ID as a HTML attributes
1. * view plaincopy to clipboardprint?

* {  
 margin: 0;  
 padding: 0;  
}     

Let’s knock the obvious ones out, for the beginners, before we move onto the more advanced selectors.

The star symbol will target every single element on the page. Many developers will use this trick to zero out the margins and padding. While this is certainly fine for quick tests, I’d advise you to never use this in production code. It adds too much weight on the browser, and is unnecessary.

The * can also be used with child selectors. view plaincopy to clipboardprint?

#container * {  
 border: 1px solid black;  
}     

This will target every single element that is a child of the #container div. Again, try not to use this technique very much, if ever.

X

view plaincopy to clipboardprint?

#container {  
   width: 960px;  
   margin: auto;  
}     

Prefixing the hash symbol to a selector allows us to target by id. This is easily the most common usage, however be cautious when using id selectors.

underscore
  • 6,495
  • 6
  • 39
  • 78