0

Why does function getElementsByClassName() work on javascript objects, but "getElementById" kick back "not a function"?

var divBox= makeDivBox(divParams);
var divContents = divBox.getElementById("divID");

errors : divBox.getElementById is not a function

But :

var divContents = divBox.getElementsByClassName("divClass")[0];

has no issue. Why?

edit: see similar courtesy of @rajuGT

Community
  • 1
  • 1
Apollo Creed
  • 219
  • 3
  • 18

2 Answers2

3

You appear to have a couple issues.

  1. divBox.getElementById("divID"); doesn't work because getElementById() is only a method on the document object. It is not a method on other types of objects. So, the divBox element does not have that method. You could use document.getElementById("divID") instead if there was only one divID in the entire document and if divBox was already inserted into the document.

  2. var divContents = divBox.getElementsByClassName("divClass")[0]; works because .getElementsByClassName() is a method on all DOM objects so it works when you call it on divBox.

You call getElementById() like this document.getElementById("someID").

If you want to find something in a particular part of the subtree, you can use element.querySelectorAll("#someID") or if you want to have more than one object with a given identifier, then you can use a class name and use functions that find objects with a given class name.

As to your specific questions:

divBox.getElementById is not a function

That is because geetElementById() is only a method on the document object and divBox is not a document object so it does not have that method, therefore you get the error you are seeing.

Why does this have no issue:?

var divContents = divBox.getElementsByClassName("divClass")[0];

That is apparently because divClass is a class name, not an id value and all HTML elements contain the getElementsByClassName() method so you can call it on divBox just fine.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 3
    I'm not sure about the usefulness of editing you answer to simply make it look like the other answer to the question. You could simply upvote that answer instead. – Fenton Nov 09 '15 at 21:39
  • @SteveFenton - The other answer is wrong and does not deserve an upvote. Read my answer. I'm actually answering the question. The other answer does not actually answer the question and provides wrong information about the problem. I didn't copy anything. I answered the actual problem asked about in the question. – jfriend00 Nov 09 '15 at 21:43
  • Why the downvote when this is the only answer that actually provides a full and complete answer to each of the questions asked by the OP? – jfriend00 Nov 09 '15 at 21:45
  • @jfriend00: `This is because IDs are supposed to be unique in the entire document` any given element *is* a subset of the document and therefore is *still* a unique identifier in that subgroup. If this is a case of "that's simply how it's defined" ok, but "being a unique identifier" is not really a logical justification... – Apollo Creed Nov 09 '15 at 22:12
  • 1
    @ApolloCreed - The HTML5 specification says that an ID value must be unique in the entire document. This isn't something I made up. It's how the specification was written. As my answer says, you can use `element.querySelectorAll("#myID")` if you want to do a scoped search for an ID. But, if the reason you are doing is is that you have duplicate IDs in your document, then your HTML is illegal and you should probably be using class names rather than IDs. – jfriend00 Nov 09 '15 at 22:17
  • @jfriend00 `querySelectorAll` -what a fantastic function, I had no idea it even existed. Thank you very much. `duplicate IDs` No, I am using id's correctly (afaik), It just happens I needed to select by id within a div that wasn't attached to the page/dom yet. as to my original question, I'm getting the impression `getelementbyid` is tailored specifically for the document object, and I should probably be using querySelectorAll for class selection too (on specific elements, as opposed to getelementsbyclass), yes? – Apollo Creed Nov 09 '15 at 22:30
  • @ApolloCreed - `querySelectorAll()` is just more powerful than `getElementsByClassName()` because you can use all supported CSS selectors with `querySelectorAll()`. I personally prefer `querySelectorAll()` as a more general purpose tool, but if you're searching only for a single class name, then either can work. – jfriend00 Nov 09 '15 at 22:31
1

It is because the id should be unique to the page/document.

So calling from the document and from the element should be same always. Hence providing the method for other DOM nodes is not useful at all and hence the getElementById is not available/added to the other DOM elements.

where as getElementsByClassName returns all DOM elements for the given className when called on document node. If called with any other DOM element, only child nodes which have the given className DOM nodes will be returned. Here, the behavior is different compared to the getElementById, hence this method is available to all DOM nodes.

rajuGT
  • 6,224
  • 2
  • 26
  • 44
  • You can't call it from a given element. It's not a method of regular elements. It's only a method of the `document` object. – jfriend00 Nov 09 '15 at 21:38
  • 1
    @jfriend00 Yes, I have mentioned that, why it is not in the regular elements. – rajuGT Nov 09 '15 at 21:39
  • No. You're saying that it can be called from the element and that is simply NOT the case. – jfriend00 Nov 09 '15 at 21:40
  • 1
    This answer does NOT answer the question in any way. – jfriend00 Nov 09 '15 at 21:43
  • Okay corrected it. But the OP question was, why getElementById is not available in other DOM nodes. So, I just explained that part, why it cant be. – rajuGT Nov 09 '15 at 21:44
  • @rajuGT any given element is a subset of the document and therefore any unique identifier within the document is still a unique identifier within an subset of the document. If this is a case of "that's simply how it's defined" ok, but "being a unique identifier" is not really a logical justification for this limitation on where a function can be called... – Apollo Creed Nov 09 '15 at 22:15
  • 1
    Hmmm, depends. Few people accept it and few not, but it is the w3c community which decided the api and made it only for document. Check this answer too http://stackoverflow.com/a/16475657/1699979, and if at all you want to add for all element, check this answer http://stackoverflow.com/a/5683184/1699979 – rajuGT Nov 09 '15 at 22:35