Let's take a look. Code (Supports multiple class queries and queries within a certain range)
Copy code The Code is as follows :/*
* Obtain the Element Set Based on the element clsssname.
* @ Param fatherid the ID of the parent element. The default value is document.
* @ Tagname the label name of the sub-element
* @ Classname A classname string separated by Spaces
*/
Function getelementsbyclassname (fatherid, tagname, classname ){
Node = fatherid & document. getelementbyid (fatherid) | document;
Tagname = tagname | "*";
Classname = classname. Split ("");
VaR classnamelength = classname. length;
For (VAR I = 0, j = classnamelength; I <j; I ++ ){
// Create a regular expression matching the class name
Classname [I] = new Regexp ("(^ | \ s)" + classname [I]. replace (/\-/g, "\-") + "(\ s | $ )");
}
VaR elements = node. getelementsbytagname (tagname );
VaR result = [];
For (VAR I = 0, j = elements. length, K = 0; I <j; I ++) {// cache Length attribute
VaR element = elements [I];
While (classname [k ++]. Test (element. classname) {// optimized the loop
If (k = classnamelength ){
Result [result. Length] = element;
Break;
}
}
K = 0;
}
Return result;
}
Okay. Let's test:Copy codeThe Code is as follows: <Div id = "Container">
<SPAN class = "aaa zzz ccc"> </span>
<Div class = "aaa bbb ccc"> </div>
</Div>
<Div class = "aaa bbb ccc"> </div>
Copy codeThe Code is as follows: window. onload = function (){
Alert (getelementsbyclassname (document, "Div", "aaa ccc"). Length); // 2
Alert (getelementsbyclassname ("container", "Div", "aaa ccc"). Length); // 1
Alert (getelementsbyclassname ("container", "span", "AAA Zzz"). Length); // 1
}
The result is correct.
Native getelementsbyclassname
Some people may ask, the native method call efficiency is the highest, and many browsers have already implemented the getelementsbyclassname method. Why didn't we call the native method before calling the custom method?
Yes, the native efficiency is very high. It supports queries with multiple class conditions, but the biggest problem is that it does not support getelementsbyclassname ("container", "Div ", "aaa ccc"), which is used to find the specified element as the specified class in the specified tag.
Therefore, native method calls are discarded here.
Questions about cyclic Optimization
In the code, you will see that I have cached the length of the array to improve efficiency. In fact, there is a very hidden problem here, that is, the access Length attribute of the array is very different from the access Length attribute of the htmlcollection. In an array, length is a common attribute and no additional operations are performed during access. To see htmlcollection, we often use htmlcollection as an array, but in fact, it is an object that automatically changes according to the DOM structure. Each time you access the attributes of an htmlcollection object, it will perform a complete match on all the nodes in the Dom. That is to say, each time you access the length of the htmlcollection object, the set object will be updated, which consumes a lot of performance. Therefore, we recommend that you cache the length of this htmlcollection loop operation.
Additional gains
This is about the efficiency comparison between the ways to put elements into the array.
Let's take a look at the Code: Copy code The Code is as follows: // method 1
VaR arr = [];
VaR start = new date ();
For (VAR I = 0; I <100000; I ++ ){
Arr. Push (I );
}
// Method 2
VaR arr = [];
VaR start = new date ();
For (VAR I = 0; I <100000; I ++ ){
Arr [arr. Length] = I;
}
Let's guess, which one is more efficient! After testing, the efficiency of the second method is higher than that of the first method.
Reminder:
This version is not compatible with ie5. The following is my explanation:
1. When you get the statistics from the thousands, the ie5 testers who are crazy about money click and professionalProgramI'm curious about ie5. It is estimated that only ie5 is burned to the ashes.
2. You want to believe that the use value of ashes tends to be zero.
3. If you haven't been able to convince you, I 'd like to say that you are very professional! Now, is there ie3, ie2, or IE? Ff1, nn4..., I think you should implement it together.
Some frankness: I didn't quite convince myself. Alas, let's give an ie5 solution:
Ie5 does not support the getelementbytagname ("*") format, so here we need to handle it:
VaR elements = (tagname = '*' & node. All )? Node. ALL: node. getelementsbytagname (tagname );
Well, let's not talk about it much. This function is simple and practical. I also wrote comments on the code to understand that there should be no problem.