By Tanner Babcock


2011-10-19 00:45:09 8 Comments

Alright, I've dabbled in JavaScript before, but the most useful thing I've written is a CSS style-switcher. So I'm somewhat new to this. Let's say I have HTML code like this:

<div id="foo">
    <div class="bar">
        Hello world!
    </div>
</div>

How would I change "Hello world!" to "Goodbye world!" ? I know how document.getElementByClass and document.getElementById work, but I would like to get more specific. Sorry if this has been asked before.

6 comments

@Joseph Marikle 2011-10-19 00:47:49

Well, first you need to select the elements with a function like getElementById.

var targetDiv = document.getElementById("foo").getElementsByClassName("bar")[0];

getElementById only returns one node, but getElementsByClassName returns a node list. Since there is only one element with that class name (as far as I can tell), you can just get the first one (that's what the [0] is for—it's just like an array).

Then, you can change the html with .textContent.

targetDiv.textContent = "Goodbye world!";

var targetDiv = document.getElementById("foo").getElementsByClassName("bar")[0];
targetDiv.textContent = "Goodbye world!";
<div id="foo">
    <div class="bar">
        Hello world!
    </div>
</div>

@rvighne 2013-12-24 05:05:37

Getting the parent by ID is not necessary in this case. document.getElementsByClassName would work fine.

@Joseph Marikle 2013-12-24 14:30:12

@rvighne the exact requirements of OP was that he "would like to get more specific". The person asking the question was asking how he could be more specific in his DOM tree traversal. The use of getElementByClassName was not a point of confusion, but I can see how someone might easily think I was indicating both as necessary. They are not. If you want to target only elements of a certain class that are under a particular node of a given ID as opposed to elements of that same class under a different node, this is what you would use.

@codescribblr 2018-09-24 18:00:38

Might be good to edit this answer and change .innerHtml to .textContent for the security benefit of copy/paste coders.

@Benjamin Werner 2017-10-27 22:47:32

THe easiest way to do so is:

function findChild(idOfElement, idOfChild){
  let element = document.getElementById(idOfElement);
  return element.querySelector('[id=' + idOfChild + ']');
}

or better readable:

findChild = (idOfElement, idOfChild) => {
    let element = document.getElementById(idOfElement);
    return element.querySelector(`[id=${idOfChild}]`);
}

@hardik akbari 2015-08-01 18:22:11

You should not used document.getElementByID because its work only for client side controls which ids are fixed . You should use jquery instead like below example.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>                                                                                                             
<div id="foo">
   <div class="bar"> 
          Hello world!
     </div>
</div>

use this :

$("[id^='foo']").find("[class^='bar']")

// do not forget to add script tags as above

if you want any remove edit any operation then just add "." behind and do the operations

@Danejir 2016-07-25 03:09:43

Using a thermonuclear weapon to kill a deer will work, but is slight overkill. Using a multi-kb jQuery library to select an element when Javascript offers that functionality in it's base code is slightly more overkill.

@Avi Shimshilashvili 2015-10-18 13:17:56

Recursive function :

function getElementInsideElement(baseElement, wantedElementID) {
    var elementToReturn;
    for (var i = 0; i < baseElement.childNodes.length; i++) {
        elementToReturn = baseElement.childNodes[i];
        if (elementToReturn.id == wantedElementID) {
            return elementToReturn;
        } else {
            return getElementInsideElement(elementToReturn, wantedElementID);
        }
    }
}

@Jannik 2018-04-20 11:23:36

There is a minor bug in the sample above. Instead of instantly returning in the else path you have to check if something was found first. Otherwise the other child nodes will not be looped through. Something like this: if(elementToReturn) { return elementToReturn; }

@John Hartsock 2011-10-19 00:53:10

If this needs to work in IE 7 or lower you need to remember that getElementsByClassName does not exist in all browsers. Because of this you can create your own getElementsByClassName or you can try this.

var fooDiv = document.getElementById("foo");

for (var i = 0, childNode; i <= fooDiv.childNodes.length; i ++) {
    childNode = fooDiv.childNodes[i];
    if (/bar/.test(childNode.className)) {
        childNode.innerHTML = "Goodbye world!";
    }
}

@user113716 2011-10-19 01:04:38

getElementsByClassName doesn't work in IE8 either, but you can use querySelectorAll in its place (pretty much anyway).

@John Hartsock 2011-10-19 01:10:02

@Ӫ_._Ӫ ... lol...your correct but you just prove my answer even more. You cannot rely on getElementsByClassName if your page needs to function across multiple browsers. jQuery would definately be an option but so whould the above code.

@user113716 2011-10-19 01:18:06

Yes, I meant that comment in support of your answer, but then also to point out that it's possible to use qSA in a shim so that you can still use native code in IE8. Although taking a closer look at your solution, you've got a few things that need fixing.

@John Hartsock 2011-10-19 01:20:40

@Ӫ_._Ӫ ... curious what do you see...because I am not seeing it.

@user113716 2011-10-19 01:22:46

var i = 0, var child = fooDiv.childNodes[i] is invalid. i <= fooDiv.childNodes doesn't really make sense. childNode.className.test("bar") There's no childNode variable, and a string doesn't have a test() method.

@John Hartsock 2011-10-19 01:26:16

@Ӫ_._Ӫ your correct about i<= fooDiv.childNodes as it should be i <= fooDiv.childNodes.length and my test() is screwed up but...var i = 0, var child = fooDiv.childnodes[i] is completely valid

@user113716 2011-10-19 01:27:39

var i = 0, var child = fooDiv.childnodes[i] Nope, it's a syntax error. ;) You need to drop the second var because var is a statement, not an expression.

@John Hartsock 2011-10-19 01:31:22

@Ӫ_._Ӫ...wow my eyes are getting to me...this is what happens when you look at code too much with out testing.

@user113716 2011-10-19 01:35:42

That's much better, but your code is only ever testing the element at index 0, so the loop isn't necessary. If you meant to iterate over all child nodes, you'd need to do child = childNodes[i] inside the loop, otherwise you'll just test the first one over and over. In the example in the question, the first childNode will be a text node in many browsers, so there's that issue too. ;)

@user113716 2011-10-19 02:06:52

...fixed it by changing child to childNode, and moving the assignment inside the loop. Having the assignment at the top would only work if you did for (var i = 0, childNode; childNode = fooDiv.childNodes[i]; i ++) { ... }

@jfriend00 2011-10-19 00:46:59

You can do it like this:

var list = document.getElementById("foo").getElementsByClassName("bar");
if (list && list.length > 0) {
    list[0].innerHTML = "Goodbye world!";
}

or, if you want to do it with with less error checking and more brevity, it can be done in one line like this:

document.getElementById("foo").getElementsByClassName("bar")[0].innerHTML = "Goodbye world!";

In explanation:

  1. You get the element with id="foo".
  2. You then find the objects that are contained within that object that have class="bar".
  3. That returns an array-like nodeList, so you reference the first item in that nodeList
  4. You can then set the innerHTML of that item to change its contents.

Caveats: some older browsers don't support getElementsByClassName (e.g. older versions of IE). That function can be shimmed into place if missing.


This is where I recommend using a library that has built-in CSS3 selector support rather than worrying about browser compatibility yourself (let someone else do all the work). If you want just a library to do that, then Sizzle will work great. In Sizzle, this would be be done like this:

Sizzle("#foo .bar")[0].innerHTML = "Goodbye world!";

jQuery has the Sizzle library built-in and in jQuery, this would be:

$("#foo .bar").html("Goodbye world!");

@Tanner Babcock 2011-10-19 19:22:16

Thank you, I was having trouble with document.getElementBy* . jQuery makes things so much easier.

Related Questions

Sponsored Content

43 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

41 Answered Questions

[SOLVED] For-each over an array in JavaScript

61 Answered Questions

[SOLVED] How do I include a JavaScript file in another JavaScript file?

28 Answered Questions

23 Answered Questions

[SOLVED] Get the current URL with JavaScript?

  • 2009-06-23 19:26:45
  • dougoftheabaci
  • 2858479 View
  • 3044 Score
  • 23 Answer
  • Tags:   javascript url

86 Answered Questions

[SOLVED] How do JavaScript closures work?

3 Answered Questions

57 Answered Questions

[SOLVED] How do I check if an element is hidden in jQuery?

39 Answered Questions

[SOLVED] How do you get a timestamp in JavaScript?

Sponsored Content