I'm wondering if these two expressions are equivalent, because if they are, it would make this much easier.
$('div', this).filter(':not(.trigger)')...
$('div:not([class*=trigger])', this)...
(this providing a context under which to look for the specified div)
No.
Version 1 takes all divs without the class trigger.
Version 2 takes all the divs where the attribute class contains the text trigger.
This means a div with the class mytrigger will be a match.
Selectors
EDIT
With your updated question this would be the equivalent to the first version.
$('div:not(.trigger)', this)
They're not essentially the same. The second also filters out all div's which have a class which contains "trigger" in the name, thus also e.g. "anothertrigger" and "triggerfoo".
You can also use
$('div:not(.trigger)', this)...
which is imho much clearer.
Related
I am using mouseenter and mouseleave events on some elements to change their appearance. I am able to do so using either of the following two strategies:
$(this).css('someProperty','someValue') to add and then $(this).removeAttr('style') to remove
$(this).addClass('someClass') to add and then $(this).removeClass('someClass') to remove
What is the best way to do so?
Definitely option 2. Styles should be defined in the stylesheet.
There's also toggleClass, which removes the class if it's there, but adds it if it's missing.
Note: toggleClass also lets you pass in a Boolean as the second argument, telling it whether to add or remove it (regardless of whether it currently has that class applied), so:
$(this).toggleClass('active', true);
is exactly equivalent to:
$(this).addClass('active');
This is very handy when you have a Boolean in your code already. So instead of this:
if (isUserActive()) {
$(this).addClass('active');
} else {
$(this).addClass('active');
}
You could just do this:
$(this).toggleClass('active', isUserActive());
Option 2 if you must do it in JavaScript, but for modern browsers you may be able to achieve what you're after entirely in CSS using :hover pseudo-classes.
I'd strongly recommend addClass()/removeClass(), since you can add, remove and change a whole swathe of properties with minimal jQuery.
Whereas the css() method requires you, or rather the script, to keep track of what should be changed to reflect the aesthetic change(s) to convey programmatic interaction, coupling that with the attr() method and removing the style attribute will remove all styles, even those you want the element to retain, which requires you to reassign those properties.
So, basically, option 2 is efficient, and option 1 creates unnecessary work.
There is, of course, always toggleClass(), which can promote further efficiency.
Unless you need to dynamically generate any of the CSS property values you're better of separating the styles from the javascript. So use classes instead of direct css styles.
.addClass and .removeClass is the best way because you can style you changes with your CSS ...so after a while you can easily redesign your site.
Second one is best because normally style will is common for different elements, it will generic and adding removing is good compared with adding attribute one by one.
$(this).addClass('someClass') to add and then $(this).removeClass('someClass') to remove
If you are calling this function in more than one element I suggest you to use the second one. If you needed to change the appearance again later, then you have to edit only within the css class, not in all elements
$("#" + parentElementId + " label").attr("class", "disabled")
VS
$('#radiolabel').addClass('disabled');
Which are the pros and cons?
Thanks
The two are not the same. Using attr will replace the whole attribute. addClass will add the class to the existing classes.
As the name suggests addClass is made for this specific purpose, so I'd use that.
Here are some advantages of the two ways to do this:
addClass("disabled") Pros:
If you have other classes on your object, addClass() will preserve those while adding a new class. I pretty much always want to preserve the ability to use other classes for CSS styling reasons or common selector reasons so addClass() makes it possible to add the disabled class without disturbing other classes on the same object for other reasons.
The code reads a little more self-explanatory since the name addClass() tells someone reading the code exactly what it's doing.
addClass() automatically manages separators between class names so there is no extra accumulation of separators when you have multiple class names which can occur if you just get the current classname and add onto it yourself with string manipulation.
attr("class") = "disabled" Pros:
If you only ever want one class name on the object, this one statement insures that you will have only one class name.
A direct assignment of the one class can be faster than addClass() which has to examine what's there first and add a class to the pre-existing classes which jQuery does with a regex match. Max speed would actually be with element.className = "disabled" (no jQuery at all).
I'd go for addClass, it's easier to read, and if your editor supports code completion, also faster to type.
You better go for the addClass() you will save time and writting, and gain more efficiency.
Is selecting by ID-only (or a single identifier) faster than when adding additional identifiers?
For example
$('#element')
vs
$('#container #element')
or even more specific:
$('body div#container div#element')
?
Yes, selecting by ID only should be the fastest, because jQuery (or Sizzle) can directly use getElementById. Otherwise the rest of the selector has to be evaluated as well, right to left.
$('#element') should be fastest, followed by $('div'). These map to the native functions document.getElementById and document.getElementsByTagName. Anything more complex has to go through complex scripting and document searching.
On everything but IE6, 7, and 8, $('.class') also map to the new document.getElementsByClassName function as well, but this is slower than the other two and still has to go through Sizzle if the browser doesn't support it.
You should always try to use as few selectors as you can that will correctly identify the element(s) that you wish to process. For instance if element is a unique id (as it should be), then #element will uniquely specify it and anything else will be wasteful, both in parsing and processing overhead. (This goes equally for CSS style rules, of course, although in this case the optimal choice of selectors may be different than when using jQuery.)
Actually calling
document.getElementById("element");
is fastest.
If you really want a jQuery object then call $(document.getElementById("element"));
Benchmark
I have been reading more lately about the efficiency of the different selector engines. I know that jQuery uses the Sizzle engine and this blog post about some jQuery stuff mentioned that the Sizzle engine will break apart your selector into an array then parse left to right.
It then, from right to left, begins deciphering each item with regular expressions. What this also means is that the right-most part of your selector should be as specific as possible — for instance, an id or tag name.
My question is whether it is more efficient to run a selector with just the ID specified or the tag name as well:
var div = $('#someId');
//OR
var div = $('div#someId');
Since I write my CSS in the div#someId form I tend to do my selectors the same way, am I causing Sizzle to perform extra work (assuming QuerySelectorAll is unavailable)?
jQuery and Sizzle optimize the #id selector [source] to document.getElementById(id). I think they aren't able to optimize it like this with the tag#id.
The first is faster.
BTW specifying the tag name for an #id selector is over-specifying, as there can be only one tag with a given id on the document. Over-specifying is slower even in CSS.
Rather than speculating, let's measure it!
Here's a test case with this page loaded, then matching a random element with both methods.
Make sure you scroll right down to the bottom.
http://jsperf.com/which-jquery-sizzle-selector-is-faster#runner
As you might expect, a plain id is faster than a tag qualified one (reduction to getElementByID). This is the same when using classes.
Selecting by ID is massively faster than selecting by class, mainly as IDs are guaranteed to be unique.
If you are using jQuery, you can assume a browser with getElementById. $('#someId') can be converted to document.getElementById('someId'). $('div#someId') won't be, so it will be faster to lose the tag name.
jsPerf demonstrating this. The difference is enormous.
var div = $('#someId'); //should be faster
jQuery will use getElementById() for the above selector
var div = $('div#someId'); //would probably preform slower due to finding all the divs first
jQuery will use getElementsByTagName(), then iterate though the array of elements for the above selector
You should also remember, tag names should definately be used with class selectors (whenever possible)
var div = $('div.myclass') //faster than the statement below
versus
var div = $('.myclass') //slower
JsPerf: http://jsperf.com/jquery-id-vs-tagname-id
The first one is going to be faster because it only has to check the id. The second one runs the same check AND has to make sure the tagname is correct. div#id won't give you the element with id id unless it is a div
You can see from the source code here: http://code.jquery.com/jquery-1.6.2.js in the function init.
The fastest selector is $('') which just returns an empty jQuery object immediately.
$('body') is next, which jQuery converts to document.body
The next is $('#id') which uses document.getElementById('id').
Any other selector such as $('div#id') will just become a call to $(document).find('div#id'). find() is very complex compared to any of those other solutions and uses Sizzle JS to select the div.
What is fastest in jquery/javascript?
$('#myID .myClass')
or
$('.myClass')
What is best to use in CSS?
#myID .myClass{}
or
.myClass{}
I see now that I should have explained better. Sorry!
Ofceauce ID is a faster selector in both CSS and JavaScript. But some times you need to use class since there are multiple selectors.
Say forexample that I have i BIG html document. In the middle of the page I have:
<div id="myID">
<a class="myClass">link1</a>
<a class="myClass">link1</a>
<a class="myClass">link1</a>
</div>
If I want to target all "myClass". Would it then be better to target the ID before targeting the classes? (then I wouldn't have to do domtravel of the entire HTML document) Eg.:
Would this:
$('#myID').find('.myClass')
Be faster than:
$('.myClass')
My testing on modern browsers suggests that you should go with either,
$('#id').find('.class') // or
$('.class')
but not,
$('#id .class')
Reason being that all modern browsers implement getElementsByClassName resulting in almost-constant time lookups by class name (assuming a hash implementation). Which browsers are modern is another subjective question.
They're roughly the same in most modern browsers since class-names are hashed internally. The difference is that older browsers don't have a .getElementsByClassName or equivalent method, so .myClass is parsed internally to jQuery and EVERY element in the dom is walked and checked for the classname (or it uses XPath when possible).
Always try to use #myID .myClass when possible as it allows jQuery to jump directly to #myID and traverse from there when necessary.
Let's just think logically about this for a second, and pretend that you didn't know anything about how a browser is built internally or how it accesses the DOM, but you assume that whatever it does is logical.
Therefore, doesn't it stand to reason that out of two selectors, the narrowest one would find you results faster?
You have two selectors, which translate to rough english as
Any element of the class myClass that is a child of the element with ID of myID
Any element of the class myClass
As for "What is best to use in CSS", this is completely subjective as it depends if you are intending to target all instances of .myClass or just those that are children of #myID.
Good question actually.
Say you have parsed DOM of N elements of max depth of D and CSS of S number of rules. Then the task of finding styles for all elements has computational complexity of roughly O(N*D*S).
Obviously not all of CSS selectors has the same computation complexity.
For example li.item selector and li[class ~= "item"] require exactly the same CPU resources as they are equivalents. li[class = "item"] can be computed faster as it does not require scan of white spaces.
#1 selector here:
#myID .myClass{} /* #1 */
.myClass{} /* #2 */
require more CPU resources as you need to do exactly the same amount of work as in case #2 plus you will need to scan parent/child chain (of max D elements) to find the element with "myID".
That is all about pure CSS selectors.
In jQuery & friends situation can be a bit different. Theoretically jQuery engine can use document.getElementById() to minimize the lookup set (so reduce the N number) but that will not match CSS behavior. Here is an example: http://jsfiddle.net/dnsUF/ . Here jQuery reports one element with #foo but there two such elements in fact.
Resume:
In CSS case #2 is faster
In jQuery case #1 can be faster (but technically may not be correct in CSS sense).
Here is my article about CSS selector complexity:
http://www.terrainformatica.com/2008/07/csss-and-computational-complexity-of-selectors/
And this one of how to improve it by using style sets:
http://www.terrainformatica.com/2010/09/style-sets-in-h-smile-core/
IDs will always be the fastest way to access an element, since they are unique.
Yeah, id is one of the fastest method to access element. Check it out this test http://mootools.net/slickspeed/.
#myID .myClass is definitely a better way to access the element assuming you have many elements to which the .myClass is applied.
Update - 2015 - Check yourself here
https://jsperf.com/id-vs-class-vs-tag-selectors/2
TL;DR;
Using ID $("#foo") is almost 4x faster than CSS $(".bar") on my chrome 41 on linux 64bits