In our project, there is a different functionality when one Dollar sign used $() in Chrome console vs two Dollar signs $$(), besides the known difference that $$() return an array an $() return the first element.
For example, selector for specific element, with one dollar and two dollar queries:
$$(".my-class[my-attribute='trump']") //works
$('.my-class[my-attribute=sanders]') //works
$$('.my-class[my-attribute=trump]') //not work
What is the source and explanation for this behavior?
From Chrome Developer Tools documentation:
Selecting Elements
There are a few shortcuts for selecting elements. These save you valuable time when compared to typing out their standard counterparts.
$() Returns the first element that matches the specified CSS selector.
It is a shortcut for document.querySelector().
$$() Returns an array
of all the elements that match the specified CSS selector. This is an
alias for document.querySelectorAll()
$x() Returns an array of
elements that match the specified XPath.
When you use querySelector (or $), the result is an element or null. When you use $$, the result isn't an element but an Array which can be easily iterated over. This differs from the native querySelectorAll where it returns a NodeList which is slightly harder to go over all the entries.
Regarding the quote: of course it works the same. See:
Conclusion: It's useless to quote trump. You might also end insane.
Related
Problem: using JQuery on HTML elements with Ids containing special characters.
Any special characters can be present anywhere within the Id. In 90% of the cases those are going to be spaces, full stops and dashes.
I think I found a Possible solution but can’t find any documentation that would support this.
Let’s say sElementId is an html element Id that has special characters in it.
Using the following syntax doesn’t work:
$('#'+sElementId).addClass("pointer");
but adding a pair of square brackets works like a charm:
$(['#'+sElementId]).addClass("pointer");
My question is. Is this the correct use of square brackets inside the selector?
Actually, it doesn't work, and does something you didn't expect.
From jQuery documentation:
jQuery( object )
object
Type: PlainObject
A plain object to wrap in a jQuery object.
So if you call $(["#a b"]) (or just $(["a"])) you'll get a jQuery wrapper object for that array-of-string. It looks like a typical jQuery selector object, but it isn't. addClass has no effect on that object.
$([1]).addClass("pointer") // no operation
To select the object, just use $(document.getElementById("a b")) ($() to convert it to a jQuery object).
Alternatively:
if there are multiple elements with the same id (note that this is invalid): javascript - Get multiple elements by Id - Stack Overflow
escape the id to use $(String.raw`#a\ b`) (or equivalently $("#a\\ b")): https://stackoverflow.com/a/4823616/5267751
In our project, there is a different functionality when one Dollar sign used $() in Chrome console vs two Dollar signs $$(), besides the known difference that $$() return an array an $() return the first element.
For example, selector for specific element, with one dollar and two dollar queries:
$$(".my-class[my-attribute='trump']") //works
$('.my-class[my-attribute=sanders]') //works
$$('.my-class[my-attribute=trump]') //not work
What is the source and explanation for this behavior?
From Chrome Developer Tools documentation:
Selecting Elements
There are a few shortcuts for selecting elements. These save you valuable time when compared to typing out their standard counterparts.
$() Returns the first element that matches the specified CSS selector.
It is a shortcut for document.querySelector().
$$() Returns an array
of all the elements that match the specified CSS selector. This is an
alias for document.querySelectorAll()
$x() Returns an array of
elements that match the specified XPath.
When you use querySelector (or $), the result is an element or null. When you use $$, the result isn't an element but an Array which can be easily iterated over. This differs from the native querySelectorAll where it returns a NodeList which is slightly harder to go over all the entries.
Regarding the quote: of course it works the same. See:
Conclusion: It's useless to quote trump. You might also end insane.
I recently came across this question: How do I check if an element is hidden in jQuery?
The currently accepted answer seems to indicate that $('element').is(':hidden') is preferable to $('element:hidden') because the :hidden filter is only being applied to a single element.
But... Calling .is() also adds extra overhead as you are calling an another function.
This got me thinking, does the above reasoning for using .is() hold true if the selector is a set of elements?
And what about more extreme cases? Take the following test case:
$('element.class1:not(.class2):visible[rel="foo"]')
Is it best to leave those in the selector? Or move them all into a single filter call:
$('element').filter('.class1:not(.class2):visible[rel="foo"]')
Or is it better to chain them?
$('element').is('.class1').not('.class2').is(':visible').filter('[rel="foo"]')
The currently accepted answer seems to indicate that $('element').is(':hidden') is preferable to $('element:hidden') because the :hidden filter is only being applied to a single element.
I don't read it that way at all, and assuming you're dealing with a string, then $("some-selector:hidden") isn't applied only to a single element; it's applied to all elements matching some-selector.
Or is it better to chain them?
$('element').is('.class1').not('.class2').is(':visible').filter('[rel="foo"]')
That will fail, since is returns a boolean:
.is(selector)
Description: Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments.
If you want to select elements matching multiple criteria, it's fine to put those criteria in the selector string. The only real question you should ask yourself is whether to use :hidden and other jQuery-isms in the string, since it means that jQuery can't pass the selection off to the browser's built-in (read: fast) selector engine, and has to do the work itself.
For that reason, with that example, you might prefer to move the jQuery-isms out of it:
$('element.class1:not(.class2)[rel="foo"]').filter(":visible")
Using jQuery 3.1.1, why are the results of these two different?
$('dd[data-something]').first().innerText;
^ returns undefined
$('dd[data-something]')[0].innerText;
^ returns valid data
Wouldn't the 0th element of an array also be the .first() element?
Edit: Thanks all, I got it, jQuery object versus DOM element. As the debugger clearly showed before I could delete this :) That's a clear sign its time to call it quits for the day.
Because first returns a jQuery object wrapped around the first raw DOM element in the set (which has no innerText property, but does have that handy text method), and [0] directly accesses that raw DOM element (which does have an innerText property on most browsers).
first() will return a jQuery object which is different from the normal JavaScript object and won't work with native JavaScript APIs, here's a qoute from the official documentation
the .first() method constructs a new jQuery object from the first element in that set.
The second one (index zero) will return a JavaScript object it's almost like calling the element using querySelectorAll()
So if you want to get the text use text() from jQuery and it will work
$('dd[data-something]').first().text('new text'); // this will change the text
Can anybody tell me what's the difference between referencing an element using #[objectId] or [id=objectId]?
The first one is very fast, as jQuery internally uses getElementById when it recognizes the pattern (using a regular expression).
The second one asks jQuery to iterate over all objects having an id. It's very slow. jQuery doesn't even stop iterating when it find one match in that case.
The only legitimate reason to use a [id... selector is when you don't just search by an exact id, for example you might want to search all elements whose id starts with "something" using $('[id^=something]').
Assuming you have a valid HTML (no reused id) and a valid id, you can still have problems with $('#'+someId) (for example when your id contains a quote, or anything that breaks Sizzle's pattern recognition system). In that case, use $(document.getElementById(someId)).
Following your comment : Yes, a "#" in an ID makes it impossible for Sizzle (jQuery's selector engine) to understand your selector. Sizzle uses the following regex :
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
and /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/.test('#som#thing') returns false.