36

I have a HTML as:

<div id="xyz">

 <svg>......</svg>
 <img>....</img>
 <div id = "a"> hello </div>
 <div id = "b"> hello
      <div id="b1">I m a grand child</div>     
 </div>
 <div id = "c"> hello </div>

</div>

I want to get all the children with tags as "div" of the parent element with id = xyz in a javascript variable.

Such that my output should be:

"<div id = "a"> hello </div>
 <div id = "b"> hello
      <div id="b1">I m a grand child</div>     
 </div>
 <div id = "c"> hello </div>"
Hardik Dave
  • 676
  • 1
  • 6
  • 17

5 Answers5

43

You can simply get the #xyz div first, then find all div children:

var childDivs = document.getElementById('xyz').getElementsByTagName('div')
//                        ^ Get #xyz element;         ^ find it's `div` children.

The advantage of this method over Document.querySelectorAll is that these selectors work in pretty much every browser, as opposed to IE 8/9+ for the queryselector.

Cerbrus
  • 70,800
  • 18
  • 132
  • 147
  • Will I be able to get all the divs then into a variable as a string? This does work, but returns an object. Which I am afraid is not stored correctly into my localstorage – Hardik Dave Apr 28 '14 at 08:05
  • @user3316592: Why do you want those elements stored in localstorage? What are you trying to do? – Cerbrus Apr 28 '14 at 08:11
  • As I would be able to reload these contents with changes applied on them on page refresh. So, I want to store the divs on only intoo my local storage. – Hardik Dave Apr 28 '14 at 08:15
  • Aside from the fact that storing and re-inserting raw html like that seems like a security issue, why don't you just get the html content of the `xyz` div? (`document.getElementById('xyz').innerHTML`). That's text, and easily stored / restored. Any way, that seems like a separate question. Please consider accepting this answer, as it answers the question asked. – Cerbrus Apr 28 '14 at 08:24
25

You can use querySelectorAll:

var childDivs = document.querySelectorAll('#xyz div')

A method to transform the divs to a string (to store or to alert) could be:

var divsHtml = function () {
    var divhtml = [],
        i = -1,
        divs = document.querySelectorAll('#xyz div');
    while (i++ < divs.length) {
        divs[i] && divhtml.push(divs[i].outerHTML);
    }
    return divhtml.join('');
}();

If you need compatibility for older browsers (i.c. IE<8) use @Cerbrus' method to retrieve the divs, or use a shim.

To avoid double listing of (nested) divs, you may want to use

var divsHtml = function () {
    var divhtml = [],
        i = -1,
        divs = document.querySelector('#xyz').childNodes;
    while (i++ < divs.length) {
        divs[i] &&
          /div/i.test(divs[i].tagName) &&
           divhtml.push(divs[i].outerHTML);
        /* ∟ this can also be written as:
           if(divs[i] && /div/i.test(divs[i].tagName) {
              divhtml.push(divs[i].outerHTML)
          } */
    }
    return divhtml.join('');
}();

[edit 2021] Seven years old, this answer. See this snippet for another approach.

KooiInc
  • 119,216
  • 31
  • 141
  • 177
  • Keep in mind that `querySelectorAll` is [IE 8/9+](https://developer.mozilla.org/en/docs/Web/API/Document.querySelectorAll#Browser_compatibility) – Cerbrus Apr 28 '14 at 07:59
  • It gives a [object NodeList], how can I alert it? to see the contents? I would also want to then store it into my local storage. – Hardik Dave Apr 28 '14 at 08:03
  • @user3316592: see adjusted answer. – KooiInc Apr 28 '14 at 08:13
  • It works !! However, i should be initialized to -1 otherwise it ignores the first div child in order. Thanks!! – Hardik Dave Apr 28 '14 at 08:26
  • This will completely mess up the html structure, especially if there's a few layers of nested divs. That aside, the addition that got this answer accepted doesn't answer the original question. – Cerbrus Apr 28 '14 at 08:31
  • Also, you might want to explain your use of `&&`, as programmers new to JavaScript may not understand how it works here. Not to mention `querySelector('#xyz')` being bad form in your last code block. – Cerbrus Apr 28 '14 at 08:37
9

If you want only the immediate children of xyz, you can call

var childrendivs = document.querySelectorAll('#xyz > div');

or calculate them yourself, if you use an older browser without document.querySelectorAll-Support

var childrendivs = [],
    children = document.getElementById('xyz').children;
for(var i = 0; i < children.length; i++){
    if (children[i].tagName == "DIV") {
        childrendivs.push(children[i]);
    }
}
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
7

Unless I misunderstood, this is exactly what getElementsByTagName does.

gog
  • 10,367
  • 2
  • 24
  • 38
  • It does, but how can I get only the div tags of the parent div(xyz)? I want to get all elements by tagname as "div" but of the parent(xyz). – Hardik Dave Apr 28 '14 at 07:56
  • @user3316592: just like Cerbrus said: `getElementById('xyz').getElementsByTagName` – gog Apr 28 '14 at 07:57
  • 1
    doesn't this get more than just direct children? What if I want only immediate children with the tag name? – user3294126 Jul 02 '18 at 20:41
0

To get only the direct children of a specific element tag:

// All `div` children of document (body) (including nested)
document.querySelectorAll('div')
  .forEach(elm => elm.classList.add('querySelectorAll'))


// only direct children of document (body) which matches a `div` selector
const directDivs = [...document.body.children]
  .filter(elm => elm.matches('div'))
  // style only the `div`
  .forEach(elm => elm.classList.add('direct-div-children'))
*:not(body):not(html) {
  margin: 5px;
  padding: 5px;
  border: 3px solid black;
}

.querySelectorAll { 
  background: lightyellow;
}

.direct-div-children {
  border: 3px solid red;
}
<div>
  A
  <div>A1</div>
  <div>A2</div>
</div>
<p>not a div</p>
<div>B</div>
<div>C</div>
vsync
  • 118,978
  • 58
  • 307
  • 400