Why Does Queryselector('Div Span') Match Even Though Queryselector('Div') Does Not

Why does querySelector('div span') match even though querySelector('div') does not?

console.log(p.querySelector('div'))

Finds nothing because

The querySelector() method of the Element interface returns the first element that is a descendant of the element on which it is invoked that matches the specified group of selectors. -- mdn (emphasis mine)

console.log(p.querySelector('div span'))

Matches because

The entire hierarchy of elements is considered when matching, including those outside the set of elements including baseElement and its descendants; in other words, selectors is first applied to the whole document, not the baseElement, to generate an initial list of potential elements. The resulting elements are then examined to see if they are descendants of baseElement. The first match of those remaining elements is returned by the querySelector() method. -- mdn (emphasis mine):

Thank you evolutionxbox and G-Cyrillus for your comments.

querySelectorAll only gives output for one div in grid after forEach() loop

Short answer: replace document.querySelector(".amot") with element

Explanation:

Notice the element param inside the forEach callback function

The problem is that inside the forEach loop you are using the syntax

Array.from(document.querySelectorAll(".amot")).forEach(function(element) {
document.querySelector(".amot").doStuff()
}

This means that for every iteration, you are querying the first .amot element and doing stuff to it, while the rest remain intact. Instead, you should

Array.from(document.querySelectorAll(".amot")).forEach(function(element) {
element.doStuff()
}

This way, you are applying the logic for every element in document.querySelectorAll(".amot")

Why document.querySelector fails to find class name in Javascript

<div class="Lh(21px)">Lorem ipsum dolor ...

The name of your class is Lh(21px) and not Lh, if you want to match any class name that begins with Lh, use the solution provided in this answer:

let result1 = document.querySelector('[class^="Lh"]');
console.log(result1)
<div class="" data-test="quote-mdl" data-yaft-module="tdv2-applet-summary">
<div class="Mb(25px) smartphone_Px(20px)">
<h3 class="Mb(5px)"><span>Summary</span></h3>
<div class="Lh(21px)">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed et magna magna. Praesent in condimentum quam. Phasellus dui ligula,
tincidunt porta fermentum nec. rhoncus id enim. Duis tempor, tellus at
fermentum consectetur, nisl ipsum placerat metus, sed aliquam turpis enim eget erat.
</div>
</div>
</div>

queryselectorAll with descendant not selecting correctly

This is because the first <a> tag you're trying to ignore still falls into the selector rule ul > li > a. So, even though you start the query with the <li class="test"> as the root (which does work by the way, I don't know why the other answers say that the document is still the root), the first child element it finds is the <a> tag and, indeed, it is the child of an <li> which is the child of a <ul>. The fact that this winds up going "above" your specified root is ignored.

Edit:
If you want the selector rule to be scoped to the root as well, you can use this instead:

parent.querySelectorAll(":scope ul > li > a");

And to further clarify, browser CSS engines evaluate CSS rules right-to-left. In your mind, you want the browser to start at the root (the parent <li class="test">) and then find a <ul> tag and then find a <li> tag and then find an <a> tag.

However, the browser starts with the root, but then looks for all of the <a> tags below the root. Then it checks if the <a> tag is within an <li> and then if the <li> is within a <ul>. So the <li class="parent"> tag really is the root, but it does not follow the left-to-right hierarchy of your selector rule after that, it goes right-to-left.

Is it possible that if a span is a certain color do something?

From the above comment ...

"The first question I have is, whether the OP is in control of the code. If so there is no need to make an additional action dependent on an UI change. Instead the state change should trigger the UI change and the additional change. Thus a possible clean approach was to dispatch a custom event on statechange. In case of dealing with closed (third party) code there is still the possibility of utilizing a MutationObserver"

The CustomEvent approach for code one does own and is allowed to change, and where decoupling makes sense ...

const elmNode = document.querySelector('p')

elmNode
// listen to an own custom event.
.addEventListener('uiapprovalchange', evt => {
if (evt.detail.isApproved) {

console.log('text color should have changed into an approval state');
// console.log({ evt: { detail: evt.detail } });
} else {
// console.clear();
}
console.log({ evt: { detail: evt.detail } });
});

elmNode
.addEventListener('click', ({ currentTarget }) => {
const { dataset } = currentTarget;
const doApprove = (dataset.approved !== 'true');

dataset.approved = String(doApprove);
currentTarget.style.cssText = doApprove ? "color: lime" : '';

// create and dispatch an own custom event.
currentTarget.dispatchEvent(
new CustomEvent('uiapprovalchange', {
detail: {
isApproved: doApprove,
},
}),
);
});
<p>click in order to toggle the <em>approved</em> color change</p>

Document.querySelector() is not showing all elements

Document.querySelector()

The Document method querySelector() returns the first WebElement within the document that matches the specified selector, or group of selectors. If no matches are found, null is returned.

Note: The matching is done using depth-first pre-order traversal of
the document's nodes starting with the first element in the document's
markup and iterating through sequential nodes by order of the number
of child nodes.

Syntax:

element = document.querySelector(selectors);


Document.querySelectorAll()

The Document method querySelectorAll() returns a static NodeList representing a list of the document's elements that match the specified group of selectors.

Note: Although NodeList is not an Array, it is possible to
iterate over it with forEach(). It can also be converted to a real
Array using Array.from(). However, some older browsers have not implemented NodeList.forEach() nor Array.from(). This can
be circumvented by using Array.prototype.forEach().

Syntax:

elementList = parentNode.querySelectorAll(selectors);


Using CssSelector

While using a xpath or a css-selectors would return a list of the document's elements that match the specified group of selectors.



Conclusion

As discussed above, when you use querySelector() only the first matching element is returned. If your usecase is to return all the matching element, you need to use querySelectorAll() as:

document.querySelector("div[slot^='Learner']>div>div>span")

memory js game pictures won't close

Because every pair is a match:

if (flippedCards[0].innerText === flippedCards[1].innerText)

Your elements have no text, so innerText is always an empty string. So any two cards, regardless of their images, match.

Probably the quickest solution is to compare the HTML instead:

if (flippedCards[0].innerHTML === flippedCards[1].innerHTML)

Assuming the rest of the HTML is always the same, the only different should be the src on the <img> element(s).


As an added exercise, you could also look into being more explicit in that comparison. Perhaps give each element a data-* property and compare those instead of relying on the text or HTML. Or perhaps specifically read the src property and compare those values instead of comparing the entire contents of the element(s).

querySelectorAll to include self

I still need to test whether divA matches my selector or not. Is there
a way for css selector to test an element itself?

querySelector() cannot return the context element it's running on.

What you can do is use @Andreas' solution followed by a filter()/matches() combo.

[divA, ...divA.querySelectorAll('.a')].filter(el => el.matches('.a'));


Related Topics



Leave a reply



Submit