1

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.

mike rodent
  • 14,126
  • 11
  • 103
  • 157
  • Isn't it just `el.children()` where `el` is the element you just created? – Barmar May 20 '20 at 19:50
  • Er... that would return all child elements, regardless of tag name. I'd then have to iterate through that list. I may **have** to iterate through that list! – mike rodent May 20 '20 at 19:51
  • I didn't realize "of a given tag name" referred to the elements you were looking for, I thiought that was what you were getting the children of. – Barmar May 20 '20 at 19:55
  • Get all the children and then call `filter()` to check the tag name. – Barmar May 20 '20 at 19:56
  • Aha... just tried to clear up possible lack of clarity on my part. – mike rodent May 20 '20 at 19:57
  • No familiarity with `filter` ... just looked it up. Thanks for that. So no way I can use a selector... ? – mike rodent May 20 '20 at 20:00
  • I don't think you can do it with a selector because there's no way to specify the top-level element, so you can't select only its immediate children. In the DOM you do it with the `body` selector, but there's nothing analogous in your anonymous element. – Barmar May 20 '20 at 20:02
  • Does it has other childs also other than div? – Ankit Chaudhary May 20 '20 at 20:35
  • @AnkitChaudhary ... yes, other elements and possibly other non-element nodes... otherwise the problem would not arise. – mike rodent May 20 '20 at 20:37

1 Answers1

3

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);
Ankit Chaudhary
  • 4,059
  • 1
  • 11
  • 23