I need to understand how this works so I can code the right stuff.
<div class="element">
<div class="content">
<contents>
<div class="element">
<contents>
<div class="thisClass"></div>
</div>
</div>
<div class="thisClass"></div>
</div>
I have the element that includes a child element with similar structure and classes. If I do
var element = document.querySelector('.element'); // this returns the parent
element.querySelector('.thisClass') // ok I got it so far
EDIT: I want to make sure to always get the element ('.thisClass') from the parent, no matter what is the order of the parent's child elements, and using the best possible script.
I am very tired working like a workaholic, I'm a newbie with native JS, I hope this is clear enough.
var element = document.querySelector('.element'); // this returns the parent element.querySelector('.thisClass')
what would this return and why?
It would return this element:
<div class="element">
<div class="content">
<contents>
<div class="element">
<contents>
<div class="thisClass"></div><!-- <===== Here -->
</div>
</div>
<div class="thisClass"></div>
</div>
The "why" is because querySelector
and methods like it work in document order, which is the order of the document from top to bottom (e.g., as though written out as HTML). Or to put it another way, it's a depth-first search of the element.
Re your edit:
I want to make sure to always get the element ('.thisClass') from the parent, no matter what is the order of the parent's child elements, and using the best possible script.
That completely changes the question. And the answer is: You can't use querySelector
for that (well, not without fudging things a bit). You have two options:
Loop through the parent element's childNodes
(or children
) list, or
Fudge things a bit and use querySelector
#1 is fairly obvious, but for completeness:
var element = document.querySelector('.element');
var targetElement, node;
for (node = element.firstChild; node; node = node.nextSibling) {
if (node.nodeType === 1 && node.className.match(/\bthisClass\b/)) {
targetElement = node;
break;
}
}
Or if you can rely on using a modern-ish browser, you can use firstElementChild
and nextElementSibling
and skip the nodeType
check.
#2 is more work for the browser and probably hard to justify in this case where you're just looking for something simple like a class name, but here's what fudging querySelector
looks like:
var markerId = "some-unique-string-you-know-is-not-used-as-an-id-in-your-document";
var element = document.querySelector('.element');
if (!element.id) {
element.id = markerId;
}
var targetElement = document.querySelector('#' + markerId + ' > .thisClass');
if (element.id == markerId) {
element.id = "";
}
You can see how that works: We make sure the element has an id
, then use a direct child combinator with document.querySelector
(not element.querySelector
) looking for the first immediate child of the element with that id
. Then we remove the id
if we set it.
Again, it's more work for the browser, and the code's not shorter, but there might be use cases if you have complex selectors...