Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About querySelector() with multiple selectors

I had a situation in which I wanted to focus either an input tag, if it existed, or it's container if it didn't. So I thought of an intelligent way of doing it:

document.querySelector('.container input, .container').focus();

Funny, though, querySelector always returns the .container element.

I started to investigate and came out that, no matter the order in which the different selectors are put, querySelector always returns the same element.

For example:

var elem1 = document.querySelector('p, div, pre');
var elem2 = document.querySelector('pre, div, p');

elem1 === elem2; // true
elem1.tagName;   // "P".

My question is: What are the "reasons" of this behavior and what "rules" (if any) make P elements have priority over DIV and PRE elements.

Note: In the situation mentioned above, I came out with a less-elegant but functional solution:

(document.querySelector('.container input') ||
 document.querySelector('.container')       ).focus();
like image 507
mauroc8 Avatar asked Mar 10 '16 18:03

mauroc8


People also ask

Can you select multiple elements with querySelector?

Yes, because querySelectorAll accepts full CSS selectors, and CSS has the concept of selector groups, which lets you specify more than one unrelated selector.

How do I select multiple ids in querySelector?

Use the querySelectorAll() method to select elements by multiple ids, e.g. document. querySelectorAll('#box1, #box2, #box3') . The method takes a string containing one or more selectors as a parameter and returns a collection of the matching elements. Here is the HTML for the examples in this article.

What does the querySelector () method do?

The querySelectorAll() method returns all elements that matches a CSS selector(s). The querySelectorAll() method returns a NodeList.


3 Answers

document.querySelector returns only the first element matched, starting from the first element in the markup. As written on MDN:

Returns the first element within the document (using depth-first pre-order traversal of the document's nodes|by first element in document markup and iterating through sequential nodes by order of amount of child nodes) that matches the specified group of selectors.

If you want all elements to match the query, use document.querySelectorAll (docs), i.e. document.querySelectorAll('pre, div, p'). This returns an array of the matched elements.

like image 190
Thijs Kramer Avatar answered Oct 13 '22 21:10

Thijs Kramer


The official document says that,

Returns the first element within the document (using depth-first pre-order traversal of the document's nodes|by first element in document markup and iterating through sequential nodes by order of amount of child nodes) that matches the specified group of selectors.

So that means, in your first case .container is the parent element so that it would be matched first and returned. And in your second case, the paragraph should be the first element in the document while comparing with the other pre and div. So it was returned.

like image 4
Rajaprabhu Aravindasamy Avatar answered Oct 13 '22 22:10

Rajaprabhu Aravindasamy


That's precisely the intended behavior of .querySelector() — it finds all the elements in the document that match your query, and then returns the first one.

That's not "the first one you listed", it's "the first one in the document".

This works, essentially, like a CSS selector. The selectors p, div, pre and pre, div, p are identical; they both match three different types of element. So the reason elem1.tagName == 'P' is simply that you have a <p> on the page before any <pre> or <div> tags.

like image 4
VoteyDisciple Avatar answered Oct 13 '22 23:10

VoteyDisciple