mike rodent
mike rodent

Reputation: 15682

get all immediate child elements with a given tag name? Native JS only

No JQuery please.

I'm quite surprised not to have found the answer to this. I'll probably be "duped".

The problem is to get only the immediate child elements with a given tag name (e.g. DIV), so getElementsByTagName doesn't work: this will return all descendants with that tag name.

There's a nice-looking answer here, using querySelectorAll():

const childDivs = document.querySelectorAll('#xyz > div');

... but what I've done is just create an element (DIV) on the fly and made its innerHTML equal to the content of a fetch'd HTML file. The consequence of this is to make the BODY's child elements become the child elements of the created element.

So it doesn't have an ID or class, and it's not even in the DOM tree. Of course I can iterate ... but who wants to iterate in 2020! Preposterous. So how might I say:

const childDivs = container.querySelectorAll('ME > DIV');

...?

Edit

Had a go with the filter idea from Barmer:

const childEls = container.children
function checkDiv( el ){
    return el.tagName === 'DIV'
}
const childDivs = childEls.filter( checkDiv )

error: "childEls.filter is not a function"

... I think childEls (class HTMLCollection) above is one of those "Array-like" objects. So I believe you have to do this:

const childEls = container.children
const newArr = Array.prototype.slice.call( childEls );
const childDivs = newArr.filter( function( el ){ return el.tagName === 'DIV' }  )

... which works... but is, in truth, iteration. Boo.

Upvotes: 2

Views: 2451

Answers (1)

Ankit Chaudhary
Ankit Chaudhary

Reputation: 4099

A NON IE solution:

Using :scope pseudo class

The :scope CSS pseudo-class represents elements that are a reference point for selectors to match against.

const childDivs = container.querySelectorAll(':scope > div')

An IE solution:

We need to make the HTMLCollection object the scope of Array.prototype.filter to filter HTMLCollection object. That can be achieved by call,apply or bind.

Using Call:

const childDivs = Array.prototype.filter.call(childEls,checkDiv );

Using Apply:

const childDivs = Array.prototype.filter.apply(childEls,[checkDiv] );

Using Bind:

const childDivs = Array.prototype.filter.bind(childEls)(checkDiv);

Upvotes: 4

Related Questions