When using Bootstrap and jQuery, whats the best way to set properties of a DOM element?
For a div with id="myDiv", I can modify it via two methods:
document.getElementById("myDiv").innerHTML = "test123";
$("#myDiv").html("test456");
jsfiddle here
Is there any benefit in using one over the other?
You use jQuery to shorten down the length of the code you would actually write in JavaScript. Otherwise they're same, jQuery is a JavaScript's Library nothing else.
So, if you're using jQuery.
You should use
$('#myDiv').html('text');
It is the same thing that the code in JavaScript would do
document.getElementById("myDiv").innerHTML = "test123";
Same goal, less stress and less codes.
JQuery is a third party library, thus u're getting a dependency (including law).
When you use document.getElementById u get less dependency and defently need less think about licences, GPL, what-to-do-when-I-need-more-or-sell-or-kind-of and everythin else ..
..
for me better:
myfunction_changeDivContent(divName,content){
document.getElementById(divName).innerHTML = content;
}
Since you are already using jQuery, I suggest, that you use $("#myDiv").html("test456"); for your purposes, since it makes code more uniform. Not a big deal otherwise.
Related
I am starting to learn jQuery. Looking though the MVC3 project that makes use of Awesome MVC Html helpers, I have stumbled upon a javasript code that I don't know how to understand yet:
$ae.autocomplete('Requestor'
What is $ae is calling a jQuery autocomplete on in this case? ae isn't an element, so this isn't an id or class selector.
P.S. And while you are at it, please let me know what $. as in $.getJSON calls getJSON on?
Assuming that there isn't a typo, $ae is a variable. Since $ is just a javascript function you can assign the result of it to a variable, $ae = $("#myid"). While I don't know that $ae is definitely the result of that, the naming convention ($ at the beginning) makes me suspect that it is.
In jQuery, the $ is a convenient alias for the jQuery object. So $.getJSON() is calling the getJSON() method of the jQuery object. This is pretty confusing at first, but once you get used to it it's nice and concise.
It seems like common practice in jQuery development to use a $ to prefix variables that result from selecting things with jQuery, like this:
var $myList = $('.list-item');
The $ is a legal character to use in variable names, so I guess it's a reminder that the object contains a jQuery wrapped set. It's a good idea to assign the results of your selections to variables if you'll use the selected items again; otherwise you're wasting resources.
In your example, the $ae is the equivalent of something like this:
$('#my-input').autocomplete('Requestor ...
I was previously using the jQuery autosave plugin but have recently removed it. Some code is still trying to use this function, so how can I temporarily extend the jQuery object so there is an empty function to prevent errors until I can get through all of the code that is trying to use the function?
The plugin is called in this way:
jQuery().autosave.restore();
jQuery().autosave.save();
I think those are the only two functions that exist, so it would be OK to create two empty functions, but is there a way to create a catch-all function on this type of object?
Note
This is a temporary solution until I can go through a lot of code. I do believe the question is a valid coding question even if you think this workaround is not ideal (it isn't).
There is a way to do this. You can create a dummy plugin (check out jQuery's documentation for creating plugins):
(function( $ ){
$.fn.autosave = {
restore: function() {};
save: function() {};
};
})( jQuery );
I would highly recommend against doing this, however. Instead, you should look at those errors and fix them, i.e., stop your code from using them. Otherwise you're simply hiding the problem.
Nope. Standard JavaScript does not support "catch-all" methods.
I had that question in mind for a long time.
Theoretically, jQuery core function accepts an optional value that can be a DOM element - $(".searched",$("#context")[0]) - or a jQuery object - $(".searched",$("#context") ) .
I discovered that last question reading that fine article.
But i really cant see the difference between use a context and pass a more complex css expression. If there is no difference in the way it works, is there any perfomance difference?
Thanks
It gets converted to a DOM element (in Sizzle, the context portion) to search in either of your cases, ultimately doing a .find() under the covers.
If you're concerned about performance (why not be as fast as possible?), you should use this instead:
$("#context .searched")
This version gets converted back into a jQuery object:
$("#context")[0]
So it's a bit slower on the jquery side, since it has to be wrapped in a jquery object before the .find() call, that performance difference is very minimal, but it's the only difference so I'm noting it :)
The major difference would be that $(".searched", context); can take a variable as a context as well. It is effectively doing $(context).find('.searched'); under the hood, and I think the second version is more readable anyway, so I usually use that.
The use for this situation would be something like this:
$.fn.highlightSearch = function() {
return this.each(function() {
$('.searched', this).addClass('highlighted');
// the commented line performs the same thing:
// $(this).find('.searched').addClass('highlighted');
});
};
$('#context').highlightSearch();
$('.somethingElse').highlightSearch();
Notice that in this case, you can't simply append the new selector on the end of the original.
If you have no other reason to hold a copy of $('#context'), then using $('#context .searched') is going to be quicker, and simpler. However, if you already had $('#context') stored in a variable, its better to use .find(select) or the $(selector, context) form to search for your contained elements.
Readability: a CSS selector like $("#context .searched") is far more readable than the other.
Ok saddle up cowboys, because this is going to be a long one. I have been spending the morning going through some of my old code and I'm left wondering about best practices and optimzation. In order to avoid a ride down subjective lane I'll just post some examples with some hopefully easy to answer questions. I will try to keep the examples very simple for ease of an answer and to decrease the likelihood of mistakes. Here we go:
1) Assignment vs jQuery Calls
I understand that when accessing selectors it's generally considered better to assign a selector to a variable rather than make the same call more than once - ex.
$('div#apples').hide();
$('div#apples').show();
vs.
var oranges = $('div#oranges');
oranges.show();
oranges.hide();
Does this same rule apply when referencing jQuery's $(this)? Ex. A simple bit of script to make some data in a table clickable and customize the link.
$('tr td').each( function() {
var colNum = $(this).index();
var rowNum = $(this).parent().index();
$(this).wrap('<a href="example.com/hello.html?column=' + colNum + '&row=' + rowNum +'">');
})
vs.
$('tr td').each( function() {
var self = $(this);
var colNum = self.index()
var rowNum = self.parent().index()
self.wrap('<a href="example.com/hello.html?column=' + colNum + '&row=' + rowNum +'">');
});
2) this vs $(this)
Ok so this next one is something that I have wondered about for a long time but I can't seem to find any information on it. Please excuse my ignorance. When does it make sense to call the vanilla js this as opposed to the jQuery wrapped $(this)? It's my understanding that -
$('button').click(function() {
alert('Button clicked: ' + $(this).attr('id'));
});
Is much less efficient than accessing the DOM attribute of the vanilla this object like the following -
$('button').click(function() {
alert('Button clicked: ' + this.id);
});
I understand what is going on there, Im just wondering if there is a rule of thumb to follow when deciding which to use.
3) Is more specificity always better?
This one is pretty simple, is it ALWAYS beneficial to be more specific with our selectors? It's easy to see that $('.rowStripeClass') would be much slower than $('#tableDiv.rowStripeClass'), but where do we draw the line? Is $('body div#tableDiv table tbody tr.rowStripeClass') faster still? Any input would be appreciated!
If you've made it this far, thanks for taking a look! If you haven't, :p
I'll try to answer these as concisely as possible:
Cache it when it's used often, especially in a loop situation, running the same code to get the same result is never a good thing for performance, cache it.
Use this when you only need a DOM element and $(this) when you need the jQuery methods (that wouldn't be available otherwise), your example of this.id vs $(this).attr("id") is perfect, some more common examples:
Use this.checked instead of $(this).is(':checked')
Use $.data(this, 'thing') instead of $(this).data('thing')
Any other case where creating a jQuery object isn't useful basically.
Decending from an ID selector is preferred for performance...how specific do you need to be? That completely depends, in short: be as specific as you need to be.
1) Assignment vs jQuery Calls
Does this same rule apply when referencing jQuery's $(this)?
Yes, absolutely. A call to the $ function creates a new jQuery object and with it comes associated overhead. Multiple calls to $ with the same selector will create a new object every time.
2) this vs $(this)
I would say knowing the difference is important because at times it becomes crucial that you don't wrap your objects with jQuery. In most cases, you wouldn't want to do premature optimization and just to keep things consistent, always wrap them with $(this), and preferably cache it in a variable. However, consider this extreme example of an unordered list <ul> that contains a million <li> elements:
$("#someList li").each(function() {
var id = $(this).attr('id');
});
A million new objects will be created which will incur a significant performance penalty, when you could have done without creating any new objects at all. For attributes and properties that are consistent across all browsers, you could access them directly without wrapping it in jQuery. However, if doing so, try to limit it to cases where lots of elements are being dealt with.
3) Is more specificity always better?
Not always. It mostly depends on browsers, and again not worth delving into micro-optimizations unless you know for sure that something is running rather slow in your application. For example:
$("#someElement") vs $("#someElement", "#elementsContainer")
It may appear that since we are also provide a context when searching an element by id, that the second query is going to be faster, but it's the opposite. The first query translates to a direct call to the native getElementById(..) while the second one doesn't because of the context selector.
Also, some browsers might provide an interface to access elements by class name using getElementsByClassName and jQuery might be using it for those browsers for faster results, in which case providing a more specific selector such as:
$("#someElement.theClass")
might actually be a hindrance than simply writing:
$(".theClass")
This blog isn't too dated, but it supplies some answers to your questions as well as gives some more info on speeding up your site when using jquery: http://www.artzstudio.com/2009/04/jquery-performance-rules/
One of my favorites is number six which states to limit DOM manipulation. It's always a bad thing to do a .append in a for loop since each time you are appending to the DOM, which is an expensive operation.
Up to your questions:
Caching the jQuery object should yield best performance. It will avoid DOM lookups which is what can get slow when performed many times. You can benefit from jQuery chaining - sometimes there is no need for a local variable.
The same goes with $(this) when this is a DOM element. Despite the fact that this is the fastest way to obtain a jQuery object it is still slower than caching. If the vanilla DOM element would suffice - then don't call jQuery at all. The example with the id attribute is excellent - prefer this.id than $(this).attr('id) if you are not going to need $(this)
More specific selectors will decrease the DOM lookup time indeed. However there is indeed a line to be drawn - make the selectors more specific only if you are 100% sure this would improve performance in a noticeable way.
The only situations you should keep your eye on are loops and events. Because every action you make in one of these will be done in every iteration or on every event.
Assignment vs jQuery Calls
Your example is not the best. The place where you should save references to jQuery objects are the ones used in loops or events, or which are results of complex queries.
this vs $(this)
Again in performance critical situations raw dom is better. Other than that you should chose which is shorter or more readable. Surprise, surprise it's not always jQuery.
Is more specificity always better?
There are more types of specificity which are usually confused by people. One of them is useless which e.g.: a tag name for an id selector tag#id, it will be slower than a simple id. But there is another type when it will be a huge benefit to be specific.
Now this type depends on the browser, because the modern ones will sacrifice for the old ones, but it worths the trade-off This happens when you specify a tag for a class tag.class. In IE 6-7 it will be significantly faster than a simple .class, because sizzle can make use of the fast document.getElementsByTagName function. Now another type is when you specify too much ancestors. This will slow things down in every browser. This is because the selector is executed from right to left. The rule to keep in mind: always be the rightmost selector as specific as possible.
2013 blog article about the best jQuery practices
Updated answers on your question and even more regarding the best jQuery practices to apply nowadays, this article is dealing with interesting subjects that are really helpful and that you might want to read.
It deals with the subjects asked here and even more: the animate function,jQuery promises, best ways to import jQuery, jQuery events etc.
Hope that will be helpful to you!
I find myself doing a lot of this kind of JQuery:
$('.filter-topic-id').each(function () {
var me = $(this);
if (me.text() == topics[k]) {
me.parent().show();
}
});
I store $(this) in a variable called me because I'm afraid it will re-evaluate $(this) for no reason. Are the major JavaScript engines smart enough to know that it doesn't have to re-evaluate it? Maybe even JQuery is smart enough somehow?
They are not smart enough to know not to revaluate $(this) again, if that's what your code says. Caching a jQuery object in a variable is a best practice.
If your question refers to your way in the question compared to this way
$('.filter-topic-id').each(function () {
if ($(this).text() == topics[k]) { // jQuery object created passing in this
$(this).parent().show(); // another jQuery object created passing in this
}
});
your way is the best practice.
Are the major JavaScript engines smart enough to know that it doesn't have to re-evaluate it?
No. But if you are using jQuery you are presumably aiming for readability rather than necessarily maximum performance.
Write whichever version you find easiest to read and maintain, and don't worry about micro-optimisations like this until your page is too slow and you've exhausted other more significant sources of delay. There is not a lot of work involved in calling $(node).
You could try to profile your code with Firebug and see if using $(this) many times slows your app or not
There is no good way that a javascript can determine that the following is true:-
fn(x) == fn(x);
Even if this was possible not calling the second fn could only be valid if it could be guaraneed that fn has not have other side-effects. When there is other code between calls to fn then its even more difficult.
Hence Javascript engines have no choice but to actually call fn each time it is invoked.
The overhead of calling $() is quite small but not insignificant. I would certainly hold the result in a local variable as you are doing.
this is just a reference to the current DOM element in the iteration, so there's little or no overhead involved when calling $(this). It just creates a jQuery wrapper around the DOM element.
I think you'll find that calling the jQuery function by passing a dom element is perhaps the least-intensive of ways to construct the object. It doesn't have to do any look-ups or query the DOM, just wrap it and return it.
That said, it definitely doesn't hurt to use the method you're using there, and that's what I do all the time myself. It certainly helps for when you create nested closures:
$('div').click(function() {
var $this = $(this);
$this.find("p").each(function() {
// here, there's no reference to the div other than by using $this
alert(this.nodeName); // "p"
});
});