How to run getElementsByTagName on children of an element only?

I'm having trouble getting a selector to work properly.

I have this HTML:


and I'm trying to select the div tags, which are children of ui-controlgroup-controls - which means excluding whats inside the form.

This is what I'm trying:

// el is my div.wrapper element

However this does not work, because the div inside the form ends up in the selection.

How can I select the elements correctly when I don't want to use jQuery?



One way to do this is to iterate over your resulting node list and check the parent:

var nodes = el.children[0].getElementsByTagName("div");
nodes =;
nodes = nodes.filter(function(v, i){
    return v.parentElement === el.children[0]; 

Here is a demonstration of this approach:

A simpler (albeit less efficient) approach is to use querySelectorAll to retrieve the relevant nodes using a selector expression:

var divs = document.querySelectorAll('div.ui-controlgroup-controls > div')

For the browser that supports querySelectorAll:

var divs = el.children[0].querySelectorAll("div");

For the browsers that supports the usage of slice on NodeList (e.g. not IE, at least not IE < 9):

var slice =;

var divs = slice(el.children[0].children).filter(function(node) { 
               return node.tagName === "DIV"

For the browsers that doesn't support neither:

var nodes = el.children[0].children;
var divs = [];

for (var l = nodes.length, node; node = nodes[--l];) {
  if (node.tagName === "DIV")

In most browsers, you can do:

el.querySelectorAll(".ui-controlgroup-controls > div")

But this could give false positives if there are more deeply nested ".ui-controlgroup-controls" that you want to avoid.

If that's the case, just iterate the .children, and build a collection of nested divs.

var divs = [];

for (var i = 0, len = el.children.length; i < len; i++) {
    if (el.children[i].classname === "ui-controlgroup-controls") {
        for (var j = 0, lenj = el.children[i].children.length; j <, lenj; j++) {
            if (el.children[i].children[j].nodeName === "DIV") {

If it's known that you have only one ui-controlgroup-controls element, then you can get rid of the outer loop, and just use children[0].

var divs = [];

for (var j = 0, lenj = el.children[0].children.length; j <, lenj; j++) 
    if (el.children[0].children[j].nodeName === "DIV") 
<your-element>.querySelectorAll(":scope > div");

:scope is a pseudo-class representing the parent element. No support in IE, but there is a shim.


Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.