Analysis of jquery each () Method usage and optimization (1/2)

Source: Internet
Author: User
Tags comments

First look at the official introduction

JQuery traversal-each () method

Definitions and usage

Each () method provides a function to be run for each matching element.

Tip: Returning false can be used to stop loops early.

Grammar

$ (selector). each (function (index,element))

Instance

Output text for each LI element:

The code is as follows Copy Code

$ ("button"). Click (function () {
$ ("Li"). each (function () {
Alert ($ (this). Text ())
});
});

This is just a super simple introduction, let's take a closer look at each () method

Both jquery and jquery objects implement this method, and for jquery objects, We simply delegate each method by simply delegating the jquery object as the first parameter to the each method of jquery. In other words: jquery provides each method to make a method call to all the child elements in the object provided by the parameter. The jquery object provides each method to invoke the child elements within jquery.

The code is as follows Copy Code

Jquery.prototype.each=function (FN, args) {

Return Jquery.each (this, FN, args);

}

Let's look at the concrete implementation of each method provided by JQuery, Jquery.each (Obj,fn,arg)

The method has three parameters: the object obj to operate, the function FN to operate, and the function's parameter args.

Let's discuss it according to the OJB object:

1. obj object is an array

Each method invokes the FN function of the neutron element of the array, until the result returned by a call to a child element is false, that is, we can exit each method call when the supplied FN function is processed so that it satisfies a certain condition. When the arg argument is supplied by the each method, the argument passed in by the FN function is arg, otherwise: the child element Index, the child element itself.

2. obj object is not an array

The biggest difference between this method and 1 is that the FN method is carried out without regard to the return value. In other words, all the properties of the Obj object are invoked by the FN method, even if the FN returns false. Calling incoming arguments is similar to 1.

The code is as follows Copy Code

Jquery.each=function (obj, FN, args) {
if (args) {
if (obj.length = = undefined) {
for (var i in obj)
Fn.apply (obj, args);
}else{
for (var i = 0, ol = Obj.length i < ol; i++) {
if (fn.apply (obj, args) = = False)
Break
}
}
} else {
if (obj.length = = undefined) {
for (var i in obj)
Fn.call (obj, I, obj);
}else{
for (var i = 0, ol = obj.length, val = obj[0]; I < ol && Fn.call (val,i,val)!== false; val = Obj[++i]) {}
}
}
return obj;
}

Of particular note is that the specific invocation method of FN in each method does not take the form of a simple FN (i,val) or FN (args), but rather a fn.call (val,i,val) or fn.apply (Obj.args), which means that In your own implementation of FN, you can directly refer to an array or a child element of an object by using the this pointer. This approach is one of the most used implementations of jquery.

Ways to jump out of each loop


the correct answer is to use return false;

jquery iterates through the selected objects with each more convenient. A kind of application is to find the inside meet the conditions of the object, to jump out of this cycle, the original JavaScript out of the cycle of the general use of break, encountered this problem, subconsciously used the break, want to jump out of this cycle.

Result error

Syntaxerror:unlabeled break must be inside loop or switch

After learning to find, should use a return false;
jquery jumps out of each loop to implement break and continue functions:

Break with return false; Continue with return ture;

The code is as follows Copy Code

jquery jumps out of each loop instance
var arr = ["abc", "EF", "gggg"];
$.each (arr, function (index, value)
{
If (This = = "abc")
return false;
}
);

jquery returns false; just jump out of the loop ~ do you want to return the value or do it outside the loop?

The code is as follows

The code is as follows Copy Code
function Test () {
var success = false;
$(..). each (function () {
If (..) {
Success = true;
return false;
}
});
return success;
}


One optimization experience for each () function

It's really easy to use a problem if you just stay on the level of jquery and don't know what it is. That is why I have not been advocating jquery in recent times, and this framework's API setting has misled people into misleading.

The code is as follows Copy Code


$.fn.beautifytable = function (options) {
Define default configuration items, and then overwrite with options
Return This.each (function () {
var table = $ (this),
tbody = Table.children (' tbody '),
TR = Tbody.children (' tr '),
th = tbody.children (' th '),
td = Tbody.children (' TD ');

Class for individual content
Table.addclass (Option.tableclass);
Th.addclass (Options.headerclass); 1
Td.addclass (Options.cellclass); 2

Class of odd and even rows
Tbody.children (' Tr:even '). addclass (Options.evenrowclass); 3
Tbody.children (' tr:odd '). addclass (Options.oddrowclass); 4

Alignment method
Tr.children (' Th,td '). CSS (' text-align ', options.align); 5

Add Mouse suspension
Tr.bind (' mouseover ', addactiveclass); 6
Tr.bind (' mouseout ', removeactiveclass); 7

Click Color
Tr.bind (' click ', Toggleclickclass); 8
});
};

Overall, the code is good, clear, logical, and what you want to do is clearly explained by the comments. But as the author says, when there are 120 rows in the table, ie already reflects that the script is running too long. Obviously, this function is inefficient, or even extremely low, from the performance point of view.

So, starting from the code level analysis, this is a standard jquery plug-in function, there is a typical return This.each (function () {...};), the form of code, if the author writes this code, not by the script without thinking, You should be aware of what a function of jquery has done.

In short, the Jquery.fn function, most of which is a single invocation of each, is naturally a traversal of the selected elements and a specified operation on an element. So take a look at the code above and how many traversal you've made, assuming you've chosen only 120 rows, each row has 6 columns, plus a 1-line header:

1. Traverse th, add Headerclass, element number is 6.
2. Traverse TD, add Cellclass, element number is 6*120=720.
3. To find the odd number from all TR, one traversal of all TR is required, with an element of 120.
4. Traverse Odd TR, add Evenrowclass, element number is 120/2=60.
5. To find even in all TR, one traversal of all TR is required, with an element number of 120.
6. Traverse even tr, add Oddrowclass, the element number is 120/2=60.
7. Traverse all th and TD, add Text-align, element number is 120*6+6=726.
8. Traverse all TR, add the MouseOver event, the element number is 120.
9. Traverse all TR, add the Mouseout event, the element number is 120.
10. Iterate through all TR, add the Click event, and the number of elements is 120.
for convenience, we simply assume that accessing an element in the traversal takes 10ms, so how much time does this function take? This function has encountered 2,172 elements, time consuming 21720ms, that is, 21 seconds, it is obvious that IE should be reported for too long script execution.

Know the reasons for inefficiency, to fundamentally solve, naturally have to find ways to merge the cycle, at first glance, according to the above code in the comments in the number, at least the following points can be merged:

3 and 4 can be merged into one cycle, from 120+60+120+60 to 120, and 240 less. 1, 2, and 5 can be merged into one cycle, from 6+720+726 to 726, and 726 reduced. 6, 7, 8 can be merged into one cycle, from 120+120+120 to 120, reduced by 240. Further, 3, 4 and 6, 7, 8 can be merged into one cycle and continue to reduce by 120. Add up, we have reduced the 240+726+240+120=1326 element operation altogether, total 13260ms. After optimization, our function time becomes 21720-13260=8460ms, or 8s.

There may be a doubt here, from the structure of the table, all the th and TD elements must be within TR, so why not put the 1, 2, 5 loops in the loop of the TR, forming a nested loop, not faster?

There are 2 main reasons why this is not done here:

First, no matter where the 1, 2, 5 are placed, one access to all th and TD elements will not be reduced.

On the other hand, $ (' th,td ') this selector, in sizzle, will be translated into 2 getelementsbytagname functions of the call, the first time to get all th, the second acquisition of all TD, and then to merge the collection. Since getElementsByTagName is a built-in function, it can be thought that the function is not cyclic, that is, the complexity is O (1), the same set of aggregation using an array of related functions, is the operation of memory, the complexity of the same is O (1).

Conversely, if you use the $ (' th, ' TD ') selector in the loop of the TR element, you invoke the 2 getElementsByTagName on the TR element, because the function executes the same time regardless of which element is invoked, so it is used in cyclic tr. Instead of a 119*2 function call, the efficiency does not rise and fall.

As you can see, the basic knowledge of the sizzle selector is also an important aspect of helping to optimize the jquery code.

Don't let JavaScript do everything.

Based on the previous basic optimizations, the time has been reduced from 21 seconds to 8 seconds, but the 8-second number is clearly unacceptable.

Further analysis of our code, in fact, loop traversal is the language level of content, its speed should be quite fast. And for each element of the operation, is jquery provided by the function, compared to the traversal, is to occupy most of the resources of the master. If the access element in the traversal is 10ms, you are welcome to perform a addclass at least 100ms-level consumption.

Therefore, in order to optimize the efficiency further, we have to start with reducing the operation of the elements. Again, carefully back to the code and found that the function has a lot of changes to the style, including at least:

• Add class to all th.
• Add class to all TD.
• Add class to the TR-parity line.
• Add a text-align style to all th and TD.
In fact, we know that CSS itself has a descendant selector, and the browser native to the parsing of CSS, more efficient than let JavaScript to the element one by one plus class.

Home 1 2 last page

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.