What happen when you use select# as a css selector? - javascript

I found these two element selectors: select#usuario-select and #usuario-select. Would they return the same node in case I use them as a document.querySelector() parameter?

These are CSS selectors, as you said. document.querySelector looks for the first element matching the provided CSS selector. So:
document.querySelector('select#usuario-select') looks for the first select tag with id usuario-select ( <select id='usuario-select'>)
document.querySelector('#usuario-select') looks for the first any tag with an id usuario-select (<ANYTAG id='usuario-select'>)
They would return the same node if the first element with id usuario-select is a select tag.

You may find this link helpful.
[1]https://www.w3schools.com/jsref/met_document_queryselector.asp
This sign # just simply change the text of an element with id= usuario-select

To answer your first question, the # character is used as an ID Selector.
If you have a DOM element with the id attribute set; a corresponding ID Selector can be used to query for this node.
Example:
// This is a Class Selector. It'll query for the parent div because
// it has a `class` attribute with a matching identifier.
.parent {
background-color: black;
}
// This is an ID Selector. It'll query for the H1 text element because
// it has a `id` attribute with a matching identifier.
#name {
color: white;
text-align: center;
}
// This is an Element Selector AND an ID Selector. It'll query for
// and `<img/>` DOM node that has a matching `id` attribute value.
img#avatar {
float: left;
}
<div class="parent">
<img id="avatar" src="https://via.placeholder.com/300x300">
<h1 id="name">John Doe</h1>
</div>
MDN is a great resource for learning more about selectors:
Selectors
Simple selectors
Attribute selectors
Pseudo classes and pseudo elements
Combinators and multiple selectors
As for your final question of "would (a css selector) return the same node as (the) document.querySelector (function)?", yes.
The Document.querySelector documentation can be found here.
It states the following:
Syntax
element = document.querySelector(selectors);
Parameters:
selectors:
A DOMString containing one or more selectors to match.
This string
must be a valid CSS selector string; if it isn't, a SYNTAX_ERR exception is thrown.

As far I as understand your question,
"select#usuario-select" Vs. "#usuario-select"
select#usuario-select this will select select element with ID #usuario-select your selection is specifically target select element only.
While #usuario-select this will select an element with ID #usuario-select, you don't target which element.
Since rule of thumb of CSS, ID would be always unique; therefore only one element with specified ID will be selected and returned.
Back to your question, will they return the same? - It depends on your HTML.
Suppose your HTML Makeup is like this:
<select id="usuario-select">
<option value="a">Apple</option>
<option value="b">Banana</option>
</select>
Then, either document.querySelector("select#usuario-select") or document.querySelector("#usuario-select") will return the same node.
However, if your HTML Makup is like this:
<p id="usuario-select">Hey, I has ID "#usuario-select"</p>
Then, the first select expression document.querySelector("select#usuario-select") will return none because there is not select element with ID usuario-select, insead document.querySelector("#suario-select") will return the paragraph element, the same select expression for this is document.querySelector("p#usuario-select") also return the same.
Hope this help.

Related

How to use CSS selector in JavaScript to find element that includes a specific class?

The correct way to give an element multiple classes is simply put spaces between them. Right?
Then why does the selector [class=CLASSNAME] not work unless it's the only class?
[class^=CLASSNAME] works if the class is the first one.
But how to select all elements that possess a given class, regardless of the number or order of their classes?
I want to select all the elements with class foo-bar. But the code below only selects the first one.
const selector = '[class=foo-bar]';
const divs = document.querySelectorAll(selector);
console.log([...divs].map(div => div.textContent));
<div class="foo-bar">foo</div>
<div class="foo-bar baz">bar</div>
<div class="baz foo-bar">baz</div>
When you use an attribute selector, it's matching against the entire attribute value as an ordinary string. It doesn't treat the class attribute specially, so it's not considered to be a list of classes that can be matched individually.
Just as in CSS, use .classname to match any class in the list.
const selector = '.foo-bar';
const divs = document.querySelectorAll(selector);
console.log([...divs].map(div => div.textContent.trim()));
<div class="foo-bar">foo</div>
<div class="foo-bar baz">bar</div>
<div class="baz foo-bar">baz</div>

How do you grab an element relative to an Element instance with a selector?

I am writing a small library where I am in need of selecting a relative element to the targeted element through querySelector method.
For example:
HTML
<div class="target"></div>
<div class="relative"></div>
<!-- querySelector will select only this .target element -->
<div class="target"></div>
<div class="relative"></div>
<div class="target"></div>
<div class="relative"></div>
JavaScript
var target = document.querySelectorAll('.target')[1];
// Something like this which doesn't work actually
var relativeElement = target.querySelector('this + .relative');
In the above example, I am trying to select the .relative class element relative only to the .target element whose value is stored in target variable. No styles should apply to the other .relative class elements.
PS: the selectors can vary. So, I can't use JavaScript's predefined methods like previousElementSibling or nextElementSibling.
I don't need solution in jQuery or other JavaScript libraries.
Well it should be ideally:
var relativeElement = target.querySelector('.relative');
But this will actually try to select something inside the target element.
therefore this would only work if your html structure is something like:
<div class="target">
<div class="relative"></div>
</div>
Your best bet would probably in this case be to use nextElementSibling which I understand is difficult for you to use.
You cannot.
If you insist on using the querySelector of the subject element, the answers is there is no way.
The spec and MDN both says clearly that Element.querySelector must return "a descendant of the element on which it is invoked", and the object element you want does not meet this limitation.
You must go up and use other elements, e.g. document.querySelector, if you want to break out.
You can always override Element.prototype.querySelector to do your biddings, including implementing your own CSS engine that select whatever element you want in whatever syntax you want.
I didn't mention this because you will be breaking the assumption of a very important function, easily breaking other libraries and even normal code, or at best slowing them down.
target.querySelector('.relative');
By using querySelector on the target instead of document, you scope the DOM traversal to the target element.
It is not entirely clear from your explanation, but by related i assume you mean descendant?
To get all target elements you can use
document.querySelectorAll('.target')
And then iterate the result
I found a way which will work for my library.
I will replace "this " in the querySelector with a unique custom attribute value. Something like this:
Element.prototype.customQuerySelector = function(selector){
// Adding a custom attribute to refer for selector
this.setAttribute('data-unique-id', '1');
// Replace "this " string with custom attribute's value
// You can also add a unique class name instead of adding custom attribute
selector = selector.replace("this ", '[data-unique-id="1"] ');
// Get the relative element
var relativeElement = document.querySelector(selector);
// After getting the relative element, the added custom attribute is useless
// So, remove it
this.removeAttribute('data-unique-id');
// return the fetched element
return relativeElement;
}
var element = document.querySelectorAll('.target')[1];
var targetElement = element.customQuerySelector('this + .relative');
// Now, do anything with the fetched relative element
targetElement.style.color = "red";
Working Fiddle

What is the difference between the selectors #id and [id$='id']?

What is the difference between two statements:
$("span[id$='id']").text(var);
// And
$("#id").text(var);
HTML code is : <span class="normal11" id="id"></span>
The first one is using ends with selector while the second one is using just normal id selector.
Attribute Ends With Selector [name$="value"]
ID Selector ("#id")
By the documentation on JQuery:
$("#id") uses the JavaScript function document.getElementById(), which is extremely efficient. Link.
So, the second way should be faster and should be used.
Some different between id selector and attribute selector is
Since id selector called document.getElementById(),
it only return the first element that have a id equal to that.
However, if you use attribute selector, it will return all elements that have the id attribute that equals to that.
But duplicated id is actually invalid in HTML, and should never used.
if you really want to do that, use class instead.
example
$("#id-selector").click(function(){
$("#test").css("color", "red");
});
$("#attr-selector").click(function(){
$("*[id=test]").css("color", "blue");
});
http://jsfiddle.net/toucyqas/1/

How can I use jQuery to match nth-child or last if nth not found?

I need to be able to insert some markup into a document after() the second P element in a container. If there is only one element then I need to insert after() that one. nth-child simply does not make a match if there is only one element. How can I do this?
Thanks!
Select them both, and grab the first match.
$("#foo > p:nth-child(2), #foo > p:lastChild").eq(0).append(...;
Because the results are returned in document order, you can use the 0 index to get the nth-child or if it wasn't there, it'll get the last child.
If there are other element types, and you only care about the p elements, then use nth-of-type instead.
$("#foo > p:nth-of-type(2), #foo > p:lastChild").eq(0).append(...;

Jquery selector syntax question

I encounter the following syntax:
$('#sourcePane input:checked~img');
I know it is selecting all input elements that are checked and also under the element of id= sourcePane ? right?
But what is ~img? what does ~ do?
also, the corresponding element in HTML is
<div data-module="Sources" data-module-id="sourcePane">
Why is it not id="sourcePane" but data-module-id="sourcePane" ??
a ~ b
This is the CSS 3 general sibling combinator. It means "Select all b elements that are next siblings to a.". It works like the adjacent sibling combinator a + b, but b does not have to immediately follow a.
data- Attributes
This is HTML5 syntax to create custom attributes. From the HTML5 spec:
Custom data attributes are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements.
Your selector will not work unless you either change your HTML to:
<div id="sourcePane" data-module="Sources" data-module-id="sourcePane">
or change your selector to:
$('[data-module-id="sourcePane"] input:checked~img');
The '~img' selects a sibling with the <img /> tag after the input:checked.
(see here: http://api.jquery.com/next-siblings-selector/#prevsiblings)

Categories

Resources