How to get child element by class name?
Solution 1
Use doc.childNodes
to iterate through each span
, and then filter the one whose className
equals 4
:
var doc = document.getElementById("test");
var notes = null;
for (var i = 0; i < doc.childNodes.length; i++) {
if (doc.childNodes[i].className == "4") {
notes = doc.childNodes[i];
break;
}
}
Solution 2
Use querySelector and querySelectorAll
var testContainer = document.querySelector('#test');
var fourChildNode = testContainer.querySelector('.four');
IE9 and upper
Solution 3
The accepted answer only checks immediate children. Often times we're looking for any descendants with that class name.
Also, sometimes we want any child that contains a className.
For example: <div class="img square"></div>
should match a search on className "img", even though it's exact className is not "img".
Here's a solution for both of these issues:
Find the first instance of a descendant element with the class className
function findFirstChildByClass(element, className) {
var foundElement = null, found;
function recurse(element, className, found) {
for (var i = 0; i < element.childNodes.length && !found; i++) {
var el = element.childNodes[i];
var classes = el.className != undefined? el.className.split(" ") : [];
for (var j = 0, jl = classes.length; j < jl; j++) {
if (classes[j] == className) {
found = true;
foundElement = element.childNodes[i];
break;
}
}
if(found)
break;
recurse(element.childNodes[i], className, found);
}
}
recurse(element, className, false);
return foundElement;
}
Solution 4
Use element.querySelector(). Lets assume: 'myElement' is the parent element you already have. 'sonClassName' is the class of the child you are looking for.
let child = myElement.querySelector('.sonClassName');
For more info, visit: https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector
Solution 5
Modern solution
const context = document.getElementById('context');
const selected = context.querySelectorAll(':scope > div');
Related videos on Youtube
spyderman4g63
I'm not a real programmer I just hack stuff together.
Updated on October 15, 2021Comments
-
spyderman4g63 over 2 years
I'm trying to get the child span that has a class = 4. Here is an example element:
<div id="test"> <span class="one"></span> <span class="two"></span> <span class="three"></span> <span class="four"></span> </div>
The tools I have available are JS and YUI2. I can do something like this:
doc = document.getElementById('test'); notes = doc.getElementsByClassName('four'); //or doc = YAHOO.util.Dom.get('#test'); notes = doc.getElementsByClassName('four');
These do not work in IE. I get an error that the object (doc) doesn't support this method or property (getElementsByClassName). I've tried a few examples of cross browser implementations of getElementsByClassName but I could not get them to work and still got that error.
I think what I need is a cross browser getElementsByClassName or I need to use doc.getElementsByTagName('span') and loop through until I find class 4. I'm not sure how to do that though.
-
mostar almost 12 yearsHere it is: stackoverflow.com/questions/3808808/…
-
Prinzhorn almost 12 yearsFunny enough, the more powerful
querySelectorAll
is supported by IE 8+ whereasgetElementsByClassName
is only supported by IE 9+. If you can drop IE 7, you are safe to usequerySelectorAll('.4')
. By the way,4
is an invalid class name. -
spyderman4g63 almost 12 years@paritybit that question doesn't work because it still utilizes getElementsByClassName and older version of IE don't seem to support that. edit: I'm sorry it uses tag name. This may work.
-
spyderman4g63 almost 12 years@Prinzhorn I do not have the YUI2 selector utility available in this product for some reason.
-
Prinzhorn almost 12 years@spyderman4g63 I did not talk about anything YUI2 specific.
document.querySelectorAll
is DOM and has nothing to do with YUI
-
-
spyderman4g63 almost 12 yearsThe problem is that getElementsByClassName doesn't work in IE8.
-
spyderman4g63 almost 12 yearsSorry, that # was a typo. I can select the container div, but cannot select the child elements by tag name because that function is not working in ie8.
-
spyderman4g63 almost 12 yearsThanks, but there are a variable amount of child elements.
-
Guffa almost 12 years@spyderman4g63: The
getElementsByTagName
method works in IE 8. It is supported as far back as IE 5.5. developer.mozilla.org/en-US/docs/DOM/… -
spyderman4g63 almost 12 yearsHmm. The example does work in IE8, but maybe it doesn't work in the case that you apply it to an object. In my case is set doc as a yui dom object and then use doc.getElementsByClassName. That's when it fails. edit: or maybe I don't understand how that object works and it is just a normal dom object?
-
Hank Gay almost 12 years@spyderman4g63 the YUI version of
getElementsByClassName
is a method ofYAHOO.util.Dom
. In your case, the call would look something likeYAHOO.util.Dom.getElementsByClassName('four', 'span', 'test')
. You should probably read the docs to get a more detailed understanding of what that call is doing. The short version is that it will now look forspan
elements with the classfour
underneath the DOM element withtest
as itsid
. -
Hank Gay almost 12 years@spyderman4g63 Yes, the result of the
get
call is just a DOM element. YUI doesn't take the sort of whole-sale 'wrap everything in a framework-specific object' approach that something like jQuery does, nor does it monkey-patch native objects like Prototype does (did? I haven't messed w/ Protoype in forever). In this respect, YUI is more like Dojo. -
Christian Jørgensen almost 11 yearsTo me it seemed like the question was to always get the fourth span child, thus leading to my answer. I do of course agree that a function to get whatever type of element at whatever index within an other element would be better, but I did no interpret the question like that... reading the question again I see that I totally misunderstood though :-)
-
Fran Verona over 10 yearsThis code doesn't work if element has more than one class. For example: if you're looking for elements with "one" class, and your elements have "one two three" class, this function will not find them.
-
Jya over 9 yearsquestion is about javascript not jQuery
-
James Poulose over 9 years@FranVerona Just out of curiosity, wouldn't a simple "indexOf('className') > -1" solve the multiple class issue?
-
deadboy over 9 years@JamesPoulose, it wouldn't. Consider having an element set to two classes: small and bigger. thatElement.className would return a String that equals "small bigger". If you're looking for a class called big saying myElement.className.indexOf("big") will produce something unequal to negative 1 despite that not actually being a part of the class. If you have 100% control of your class names, such a fix would work, it's just not guaranteed to, especially when your'e writing code that's going to interact code you don't have total control over.
-
WebWanderer over 8 yearsYou should use a regex match on the
className
like so:if(doc.childNode[i].className.match("\s*" + search_class + "\s*")
where the variablesearch_class
is the class name that you are looking for. -
Paul Draper almost 8 yearsNope. I don't want all descendants, just the child like the question asked.
-
Augie Gardner almost 8 yearsWhelp. Your comment was necessary. Glad I helped 13 other people who (like me) often search for similar answers to solve their similar-but-perhaps-more-complex-or-general problem.
-
Jacksonkr over 7 years
TagName
that's it! So simple. -
Louise Eggleton over 7 yearsI use this technique frequently to get the first element eg document.getElementById("test").childNodes[0]
-
Boban Stojanovski over 7 yearstnx, i think this answer suits more use cases
-
Rob over 7 yearsI was wondering if browsers finally had this functionality without requiring something like jQuery, glad to see it. If anyone is curious, looks like it's supported in most modern browsers: developer.mozilla.org/en-US/docs/Web/API/Document/…
-
Brian McCall about 6 yearsThe real problem is that Typescript generates their definitions from IE so this solution doesn't work in typescript
-
Nic about 6 years@WebWanderer That also fails in the same scenario described by Evin. You're thinking of either
\s+
-- which fails if it's the first, last, or only class -- or\b
, which would work. -
YakovL almost 5 years@LouiseEggleton there's
.firstChild
and.firstChildElement
though -
malat about 4 yearsFor some reason I had to use
let child = myElement.querySelector('sonClassName');
in my case -
Hamza Dahmoun about 4 yearsBut you have to add the dot next to the class name querySelector('.sonClassName'), otherwise it will handle it as sonClassName is a tag name not a class name
-
SUM1 about 4 yearsThis checks for all descendants, not just children.
-
SUM1 about 4 yearsFor the record, I've had both use cases, descendants slightly more often, but I came here for the child use case.
-
CaseyC over 3 yearsThis a good answer. It will fail if the element has more than one class though. You can use
String.includes('yourclass')
to avoid this though.const childNode = Array.from(parentNode.childNodes).find(({ className }) => className && className.includes('four'));
-
SapuSeven over 3 yearsCheck compatibility at caniuse.com
-
SapuSeven over 3 years@SUM1 If you don't care about IE, you can use the CSS pseudo element
:scope
to check for direct descendants like this:testContainer.querySelector(':scope > .four')
-
robsch about 3 yearsOn Stackoverflow this is an insufficient answer since you didn't explain anything.
-
Koyaanis about 3 yearsSorry I'll add a small description
-
kingurr about 3 yearsin order to get all of the children we need to use
var fourChildNode = testContainer.querySelectorAll('.four');