Translation of excellent articles. I think it will be useful both for beginners who have just started using jQuery, and for those who have been working with it for some time. And someone, perhaps, will make this wonderful library look. Many tips are not only related to jQuery, but also to JavaScript in general. For me personally, I was very, very informative, therefore I wanted to convey this “to the masses”. The translation is not literal, but conveys meaning and is maximally adapted to the Russian language.
Then everything is written on behalf of the author of the original article.Introduction
jQuery is beautiful. I have been using it for almost a year now and, although I was quite impressed at the very beginning, I like it more and more as I use it and as I learn about how it works inside.
')
I am not an expert in jQuery. And I do not even pretend, therefore, if you encounter mistakes, feel free to correct me and make suggestions for improvement (the author of the article, not the translation, needs to be corrected and sent the amendments. Deputy.) .
I call myself the “average” jQuery user and I think it will be interesting for everyone else to read and learn something from the “tricks”, “tricks” and techniques that I have mastered over the past year. The article turned out to be much longer than I originally intended, so at the very beginning I gave the “content” for easier navigation and the opportunity to skip uninteresting moments if you want.
Content
- Download the Google Code Framework
- Use the cheat sheet
- Combine all your scripts and reduce file size
- Use the power of Firebug for logging
- Minimize sampling in favor of caching
- Reduce DOM tree manipulation to a minimum
- Wrap everything into a single element when it comes to any insertion in the DOM
- Use “id” instead of class where possible
- Set context to your selectors.
- Use sequences of method calls wisely
- Learn to use the animation correctly.
- Learn to assign and delegate events.
- Use classes to save state
- Even better, use the data () built-in jQuery method to save state
- Write your own selectors
- Prepare HTML and modify it when the page is loaded
- Use “lazy loading” for specific content to gain overall speed and SEO benefits.
- Use jQuery utility functions
- Use noconflict to rename the global jquery object when using it with other frameworks.
- How to find out what pictures are uploaded?
- Always use the latest version.
- How to check if an item exists?
- Add the “JS” class to the “html” element
- Return false to cancel the default behavior.
- Short recording for the document readiness event
1. Download the framework from Google Code
Google keeps several JavaScript libraries on Google Code and there are several advantages to downloading from there compared to storing on your server. This saves traffic, provides very fast downloads and, most importantly, the library is already in the cache if the user has visited any website using this library, which was downloaded from Google Code in due time.
This is of no small importance. How many sites give out identical jQuery copies that are not cached? It is very easy to do ... <script src="http://www.google.com/jsapi"></script> <script type="text/javascript"> </script>
Or you can simply include a direct link, like this ...
Detailed instructions here .
2. Use the cheat sheet
The tip is not only about jQuery, because there are a lot of cheat sheets for most languages. It is very convenient to have on hand every function on a printed sheet of A4.http://www.gscottolson.com/weblog/2008/01/11/jquery-cheat-sheet/http://colorcharge.com/jquery/3. Combine all your scripts and reduce file size.
Well, well, this is another javascript tip. But any big project that uses jQuery with might and main, possibly uses a lot of plug-ins (the author's site uses localScroll, lightbox and preload) , so this advice is very useful here.
Browsers cannot load scripts at the same time (well, at least they cannot yet), which means that if you have several scripts loaded one by one, this reduces the overall page load time. Thus, taking into account that the scripts usually need to be loaded onto each page, it would be nice to collect them into one large file before deployment.
Some of the plug-ins can already be minimized and packaged, but you need to consider combining the remaining scripts. I personally like Packer Dean Edwards.4. Use the power of Firebug for logging
If you haven’t yet installed Firebug, immediately kill yourself with a straight razor, you really should do it. Among other very cool things, like, for example, the ability to analyze your traffic or search for problems with CSS, Firebug has excellent tools for “logging” code execution, which allows you to quickly and easily debug scripts.Here is a complete description.
My favorite features are “console.info”, which allows you to display messages and variables directly to the screen without using alert windows, and “console.time”, which makes it very easy to set a timer for a selected piece of code and see how long it takes this piece. And all this is very simple to use. console.time ('create list');
for (i = 0; i <1000; i ++) {
var myList = $ ('. myList');
myList.append ('This is a list item' + i);
}
console.timeEnd ('create list');
In this example, I deliberately wrote a very simple and useless code. In some of the following tips, I will show how you can use the timer to make improvements.5. Minimize sampling in favor of caching.
The selectors in jQuery are great. They make sampling any element of the page incredibly simple, but “under the hood” they produce a decent amount of actions and if you abuse them, then you have every chance of reducing the overall performance.
If you have to select the same element over and over (say, in a loop), it is better to simply select it once and save it in memory for the time of manipulating its contents. Take the following example where we add items to a bulleted list using a loop: for (i = 0; i <1000; i ++) {
var myList = $ ('. myList');
myList.append ('This is a list item No.' + i);
}
It takes 1066 milliseconds on my computer in Firefox 3 (just imagine how it will work in IE6!), Which is very, very slow by JavaScript standards. Now let's look at another example where we use the selector once: var myList = $ ('. myList');
for (i = 0; i <1000; i ++) {
myList.append ('This is a list item No.' + i);
}
It takes only 224 milliseconds, which is more than 4 times faster, despite the fact that we changed only one line.6. Reduce manipulations with the DOM tree to a minimum
We can make the code from the previous board even faster if we minimize the number of calls to the DOM for insertion. DOM insert operations such as .append (), .prepend (), after (), and wrap () are relatively resource-intensive and their abuse can worsen the situation.
All we need is to use a string connection to build a list and then just one function like .html () to quickly add an item to our bulleted list. Let's see an example: var myList = $ ('# myList');
for (i = 0; i <1000; i ++) {
myList.append ('This is a list item No.' + i);
}
It took me 216 milliseconds, which is slightly more than 1/5 of a second, but if we build the list items as strings and then use the .html () method to insert, like this ... var myList = $ ('. myList');
var myListItems = '';
for (i = 0; i <1000; i ++) {
myListItems + = '<li> This is the list item No.' + i + '</ li>';
}
myList.html (myListItems);
It takes 185 milliseconds, which is not much faster, but after all, 31 milliseconds less.7. Wrap everything in a single element when it comes to any insertion in the DOM
Okay, don’t even ask me why it works (I’m sure that someone can explain this more thoroughly).
In our last example, we inserted 1000 list items into a bulleted list using the .html () method.
If we placed them in the “ul” tag before insertion and placed the finished “ul” in another tag (div), then we would successfully insert only 1 tag instead of 1000, which is likely to have an effect. Something like that... var myList = $ ('. myList');
var myListItems = '<ul>';
for (i = 0; i <1000; i ++) {
myListItems + = '<li> This is the list item No.' + i + '</ li>';
}
myListItems + = '</ ul>';
myList.html (myListItems);
This time, “for everything about everything” took no less than 19 milliseconds, which is an extremely significant improvement, the productivity increased by more than 50 times compared to the first example.8. Use “id” instead of class where possible
jQuery makes selecting DOM elements by class is as simple as selecting elements by “id” in JavaScript, with the result that many people use classes much more widely than before. However, it is still much better to select elements by “id”, since jQuery uses the standard method of any browser (getElementById) for this and does not perform any additional manipulations with the DOM, which allows to achieve good performance. How good is it? Let's check.
I will use the previous example and modify it in such a way that each “li” element will have a unique class added to it. Then I will select all the elements in the loop (each once). // Create a list
var myList = $ ('. myList');
var myListItems = '<ul>';
for (i = 0; i <1000; i ++) {
myListItems + = '<li class = "listItem' + i + '"> This is the list item No. </ li>';
}
myListItems + = '</ ul>';
myList.html (myListItems);
// Select each item in the loop
for (i = 0; i <1000; i ++) {
var selectedItem = $ ('. listItem' + i);
}
Just as I expected, the browser didn’t hang up and finished its execution only after 5066 milliseconds (more than 5 seconds). So I modified the code, giving each element an id instead of a class, and then also selected each in a loop, but by id. // Create a list
var myList = $ ('. myList');
var myListItems = '<ul>';
for (i = 0; i <1000; i ++) {
myListItems + = '<li id ​​= "listItem' + i + '"> This is a list item </ li>';
}
myListItems + = '</ ul>';
myList.html (myListItems);
// Select each item in the loop
for (i = 0; i <1000; i ++) {
var selectedItem = $ ('# listItem' + i);
}
This time - only 61 milliseconds. Approximately 100 times faster.9. Set context to your selectors.
By default, when you use the selector type $ ('. MyDiv'), the whole DOM document will be accessed, which, in certain cases (for example, with a large page), can have a very significant effect on performance.
The jQuery function takes the second parameter when sampling. <i> jQuery (expression, context) </ i>
By passing the context to the selector, you tell it the element from which to start searching. Thus, the need to refer to the entire DOM document is eliminated.
To demonstrate this, again take an example from the first council. He creates a bulleted list of 1000 items, each of which has its own class. Then the script in the loop selects each item. Remember that when sampling by class, it took us about 5 seconds to select all 1000 elements. var selectedItem = $ ('. listItem' + i);
Then, I added context to jQuery using the selector only within the bulleted list. Like this: var selectedItem = $ ('. listItem' + i, $ ('. myList'));
It took 3818 milliseconds, which is still hellishly slow by itself, but this is already more than a 25% increase in speed with minimal modification of the selector.10. Use method call sequences.
One of the coolest features in jQuery is the ability to build sequences of method calls. For example, if you want to change the class of an element: $ ('myDiv'). removeClass ('off'). addClass ('on');
Most likely, you learned it in the first 5 minutes of using jQuery, but that's not all. First, it works great with line breaks (since jQuery is still JavaScript), which means that you can write beautiful code like this: $ ('# mypanel')
.find ('TABLE .firstCol')
.removeClass ('. firstCol')
.css ('background': 'red')
.append ('<span> Now this cell is red </ span>');
Using sequences in itself also helps you limit the use of selectors.
But that's not all. Let's say you want to perform several functions on an element, but one of the very first uses changed the element in some way, for example: $ ('# myTable'). find ('. firstColumn'). css ('background', 'red');
We chose a table, went further to find cells with the “firstColumn” class and painted them red.
Imagine that we need to paint all the cells with the “lastColumn” class in blue. Since we used the find () function, we filtered all the cells that are not marked with the “firstColumn” class, so we need to reuse the selector to get the table element and we cannot continue building the sequence immediately, right? Fortunately, jQuery has an end () function that returns us to the previous untouched sample, so we can continue our sequence: $ ('# myTable')
.find ('. firstColumn')
.css ('background', 'red')
.end ()
.find ('. lastColumn')
.css ('background', 'blue');
It is also easier than you might think to write your own jQuery function, which can be included in the sequence. All you need to do is write a function that modifies the element and returns it. $ .fn.makeRed = function () {
return $ (this) .css ('background', 'red');
}
$ ('# myTable'). find ('. firstColumn'). makeRed (). append ('hello');
Just right?11. Learn to use the animation correctly.
When I first started using jQuery, I was delighted with the ease of use of built-in animation like slideDown () and fadeIn () to get cool effects. It's very easy to go a little further, because the jQuery animate () method is very simple to use and at the same time very cool. In fact, if you look at the jQuery source, you can see that all these methods are such mini-abstractions, special cases of using the animate () function. slideDown: function (speed, callback) {
return this.animate ({height: "show"}, speed, callback);
},
fadeIn: function (speed, callback) {
return this.animate ({opacity: "show"}, speed, callback);
}
The animate () method simply takes any CSS style and smoothly transforms it from one value to another. Thus, you can change the width, height, transparency, background color, padding, color, font size, and in general, whatever you want.
Here, for example, so here is just to make an animated menu, the items of which increase to 100 px in height when you hover with the mouse: $ ('# myList li'). mouseover (function () {
$ (this) .animate ({"height": 100}, "slow");
});
Unlike other jQuery functions, animations are automatically lined up, so if you want the second same effect right after the first one, just call the method again, there is no need to assign events and callbacks. $ ('# myBox'). mouseover (function () {
$ (this) .animate ({"width": 200}, "slow");
$ (this) .animate ({"height": 200}, "slow");
});
If you want the effects to flow at the same time, then just specify both styles in the object's parameters and make one call. Something like that: $ ('# myBox'). mouseover (function () {
$ (this) .animate ({"width": 200, "height": 200}, "slow");
});
So you can animate any property that has a variable number value. You can also download plugins to help animate properties that by default do not want to do this. Such as colors and background colors .
12. Learn to assign and delegate events.
With jQuery, event handlers are simply assigned to DOM elements, which is great, but adding an excessive number of handlers decreases performance. Delegating event processing allows you to add fewer events that are “listened” by an element with a result that is similar in terms of functionality. The best way to understand is to see: $ ('# myTable TD'). click (function () {
$ (this) .css ('background', 'red');
});
A simple function that turns table cells into red when you click on these cells. Let's say you have a small table with 10 columns and 50 rows, but this means that already 500 event handlers are “waiting in the wings.” Maybe it would be more appropriate to assign only one event to the whole table, and then, when the table clicked, make the handler determine which cell triggered the event?
This is what is called event delegation and it is very simple to implement: $ ('# myTable'). click (function (e) {
var clicked = $ (e.target);
clicked.css ('background', 'red');
});
'e' contains information about the event, including the element on which the click occurred. All we need to do is check it and find out which cell the user clicked on. Where more convenient.
Event delegation has another mega-substantial bonus. When you bind a handler to a set of elements, it joins those and only those elements that were in that set at the time the event was assigned. If you add new elements to the DOM, which will be completely chosen by the selector, they will not have handlers. Do you understand what I'm getting at? They will have to be assigned and reassigned constantly if the elements change.
If you use delegation, you can add as many elements to the DOM as you like and the event handler will work well with them.At the time of this writing, the author used version 1.2.6, but since version 1.3, jQuery has a new functionality that addresses the problem of event reassignment - jQuery Event / live .13. Use classes to save state
This is the easiest way to store information about a piece of html. jQuery perfectly manipulates elements based on their classes, so if you need to save information about the state of an element, then why not add an additional class in order to save it?
Here is an example. We want to create a drop-down menu. When we press a button, we want the panel to appear with slideDown (), if it is closed and vice versa - disappear from slideUp (), if it is open. Let's start with HTML: <div class = "menuItem expanded">
<div class = "button">
click me
</ div>
<div class = "panel">
<ul>
<li> Menu item 1 </ li>
<li> Menu item 2 </ li>
<li> Menu item 3 </ li>
</ ul>
</ div>
</ div>
Very simple! We simply added an extra class to the wrapper element (div), which has no other role than to tell us the state of the element. So, all we need is an onclick event handler that produces a slideUp () or slideDown () of the corresponding panel when the button is pressed. $ ('. button'). click (function () {
var menuItem = $ (this) .parent ();
var panel = menuItem.find ('. panel');
if (menuItem.hasClass ("expanded")) {
menuItem.removeClass ('Exported'). addClass ('collapsed');
panel.slideUp ();
}
else if (menuItem.hasClass ("collapsed")) {
menuItem.removeClass ('collapsed'). addClass ('expanded');
panel.slideDown ();
}
});
This is a very simple example, but you can add other classes to save any kind of information about an element or fragment of HTML.
However, in all slightly more complicated cases, it is likely that it is better to use the following advice.14. Very cool - use the data () method built into jQuery to save the state.
For some reason, this is not so well documented, but jQuery has an internal data () method that can be used to store information in key / value pairs, according to any DOM element. Storing any data is as simple as this: $ ('# myDiv'). data ('currentState', 'off');
We can improve the example from the past board. We use the same HTML (except the class “expanded”) and use the data () function. $ ('. button'). click (function () {
var menuItem = $ (this) .parent ();
var panel = menuItem.find ('. panel');
if (menuItem.data ('collapsed')) {
menuItem.data ('collapsed', false);
panel.slideDown ();
}
else {
menuItem.data ('collapsed', true);
panel.slideUp ();
}
});
I’m sure you will agree that this is much more kosher :) For more information on data () and removeData (), see this page on jQuery internals .
15. Write your own selectors
jQuery contains a lot of built-in selectors for selecting elements by id, class, tag, attribute, and more. But what to do when it is necessary to select elements by some other criterion and jQuery does not have a suitable tool?
Well, the first thing that comes to mind is to add classes to the elements at the beginning, and then we will use them for selection, but in fact, writing a new selector for jQuery is not such a problem.
Until now, the best way to demonstrate this is an example: $ .extend ($. expr [':'], {
over100pixels: function (a) {
return $ (a) .height ()> 100;
}
});
$ ('. box: over100pixels'). click (function () {
alert ('The element that you have disturbed with your click is more than 100 pixels high');
});
The first block of code creates its own selector that searches for all items that are above 100 pixels. The second block simply uses the first to assign handlers for all these elements.
I will not look at all this in more detail here, but you can already imagine how super cool such a tool is and if you search Google for “custom jquery selector”, you can find a lot of interesting things.16. Prepare HTML and modify it when the page is loaded.
The title may not be so clear, but this advice will potentially improve your terrible code, reduce its weight and load time, and among other things, will help you put more keywords with SEO into the page . Take HTML like this as an example: <div class = "fieldOuter">
<div class = "inner">
<div class = "field"> This field is number 1 </ div>
</ div>
<div class = "errorBar">
<div class = "icon"> <img src = "icon.png" alt = "icon" /> </ div>
<div class = "message"> <span> This is an error message </ span> </ div>
</ div>
</ div>
<div class = "fieldOuter">
<div class = "inner">
<div class = "field"> This field is number 2 </ div>
</ div>
<div class = "errorBar">
<div class = "icon"> <img src = "icon.png" alt = "icon" /> </ div>
<div class = "message"> <span> This is an error message </ span> </ div>
</ div>
</ div>
This is an example of what form layout can be, slightly modified to illustrate our tasks. I am sure you will agree that this code is terrible and if you have a large form, you will end up with an indecently long and, to put it mildly, ugly page. It would be better to have something like this in HTML:<div class="field"> 1</div>
<div class="field"> 2</div>
<div class="field"> 3</div>
<div class="field"> 4</div>
<div class="field"> 5</div>
, — jQuery, HTML. :$(document).ready(function() {
$('.field').before('<div class="fieldOuter"><div class="inner">');
$('.field').after('</div><div class="errorBar"><div class="icon">
<img src="icon.png" alt="icon" /></div><div class="message">
<span> </span></div></div></div>');
});
, , , HTML-, .17. « » (lazy loading) SEO
HTML, — «lazy loading» - - — , AJAX- , . , — , .
. 3 , Google, . HTML load(), . :$('#forms').load('content/headerForms.html', function() {
//
// . .
});
. , . , , - , .18. jQuery
jQuery — . , JavaScript:jQuery utilities, - ( IE7 indexOf()!). jQuery , , , .
JavaScript , , , . JavaScript «select», getElementById, «» , , . jQuery :$('#selectList').val();
, jQuery .19. «noconflict» «jquery»,
JavaScript- "$" , . , . .noconflict() "$" ,var $jabrajabr = jQuery.noConflict();
$jabrajabr('#myDiv').hide();
20. ?
, , ( -, «» . .). , .
, — .load() «img» () callback-. «src» :$('#myImage').attr('src', 'image.jpg').load(function() {
alert(' ');
});
, alert , .21.
jQuery John Resig, , .
jQuery ( — . .) 1.2.6, , — Sizzle, , , Firefox, 4 . , — .22. , ?
, , , jQuery , -, DOM. - , - , , length:if ($('#myDiv).length) {
// your code
}
, .23. «JS» «html»
Karl' Swedberg', jQuery.
…
, jQuery ,
«JS» «html»:$('HTML').addClass('JS');
, , JavaScript , CSS-, , JavaScript :.JS #myDiv{display:none;}
, , JavaScript jQuery , , (, ), , JavaScript ( ), , . .
.
24. «false» -
, . :<a href="#" class="popup"> , !</a>
… :$('.popup').click(function(){
// popup'
});
… , , , . , , , «» ( #).
, — , , . «return false;» , :$('.popup').click(function(){
// popup'
return false;
});
25.
, , $(document).ready.
:$(document).ready(function (){
//
});
:$(function (){
//
});
jQuery Jon Hobbs-Smith' . , - .Update. NemeZZiZZ , «unordered list» ( « », , , , - ).
Update 2. david_mz jQuery, 1.3, (. . 12).