Preface
We cannot face the fact that many programmers do not plan their JS Code. We often write code, run, and submit quickly. However, when we continue to develop variables and functions, we have to go back and view their meanings again. The trouble starts from here. Similarly, when we get scripts from other programmers, we will encounter similar errors. Therefore, when we say "this is done, I can go on", we 'd better do the following five things for the script.
Problem description
Now we want to add hyperlink A to each DIV with the class attribute collapsible to show and hide the DIV.
The following is the implementation code written using the module function:
Copy codeThe Code is as follows: var collapser = (function (){
Var secs = document. getElementsByTagName ('div ');
For (var I = 0; I <secs. length; I ++ ){
If (secs [I]. className. indexOf ('collapsible ')! =-1 ){
Var p = document. createElement ('P ');
Var a = document. createElement ('A ');
A. setAttribute ('href ','#');
A. onclick = function (){
Var sec = this. parentNode. nextSibling;
If (sec. style. display === 'None '){
Sec. style. display = 'block ';
This. firstChild. nodeValue = 'collapse'
} Else {
Sec. style. display = 'none ';
This. firstChild. nodeValue = 'expand'
}
Return false;
};
A. appendChild (document. createTextNode ('expand '));
P. appendChild ();
Secs [I]. style. display = 'none ';
Secs [I]. parentNode. insertBefore (p, secs [I]);
}
}
})();
The above code has accurately implemented the desired results. However, we can further refactor the code above.
Step 1: separation of style (CSS) and behavior (JavaScript)
We can add a CSS class selector to eliminate the styles set in JS. This phenomenon is often encountered by beginners.
Copy codeThe Code is as follows: var collapser = (function (){
Var secs = document. getElementsByTagName ('div ');
For (var I = 0; I <secs. length; I ++ ){
If (secs [I]. className. indexOf ('collapsible ')! =-1 ){
Secs [I]. className + = ''+ 'collapsed ';
Var p = document. createElement ('P ');
Var a = document. createElement ('A ');
A. setAttribute ('href ','#');
A. onclick = function (){
Var sec = this. parentNode. nextSibling;
If (sec. className. indexOf ('collapsed ')! =-1 ){
Sec. className = sec. className. replace ('collaped ','');
This. firstChild. nodeValue = 'collapse'
} Else {
Sec. className + = ''+ 'collapsed ';
This. firstChild. nodeValue = 'expand'
}
Return false;
}
A. appendChild (document. createTextNode ('expand '));
P. appendChild ();
Secs [I]. parentNode. insertBefore (p, secs [I]);
}
}
}) (); Step 2: Further Code Performance Optimization
Here we can do two things: 1. The length attribute of secs in the loop statement can be saved as a variable. 2. Create a reusable function for the event processor. The advantage is to reduce the number of event processors and memory usage.
Copy codeThe Code is as follows: var collapser = (function (){
Var secs = document. getElementsByTagName ('div ');
For (var I = 0, j = secs. length; I <j; I ++ ){
If (secs [I]. className. indexOf ('collapsible ')! =-1 ){
Secs [I]. className + = ''+ 'collapsed ';
Var p = document. createElement ('P ');
Var a = document. createElement ('A ');
A. setAttribute ('href ','#');
A. onclick = toggle;
A. appendChild (document. createTextNode ('expand '));
P. appendChild ();
Secs [I]. parentNode. insertBefore (p, secs [I]);
}
}
Function toggle (){
Var sec = this. parentNode. nextSibling;
If (sec. className. indexOf ('collapsed ')! =-1 ){
Sec. className = sec. className. replace ('collaped ','');
This. firstChild. nodeValue = 'collapse'
} Else {
Sec. className + = ''+ 'collapsed ';
This. firstChild. nodeValue = 'expand'
}
Return false;
}
}) (); Step 3: Add a configuration object
Use the configuration object to store hard encoding in the Code, such as text labels or custom attribute names. It is conducive to subsequent maintenance.
Copy codeThe Code is as follows: var collapser = (function (){
Var config = {
IndicatorClass: 'collapsible ',
CollapsedClass: 'collapsed ',
CollapseLabel: 'collapse ',
ExpandLabel: 'expand'
}
Var secs = document. getElementsByTagName ('div ');
For (var I = 0, j = secs. length; I <j; I ++ ){
If (secs [I]. className. indexOf (config. indicatorClass )! =-1 ){
Secs [I]. className + = ''+ config. collapsedClass;
Var p = document. createElement ('P ');
Var a = document. createElement ('A ');
A. setAttribute ('href ','#');
A. onclick = toggle;
A. appendChild (document. createTextNode (config. expandLabel ));
P. appendChild ();
Secs [I]. parentNode. insertBefore (p, secs [I]);
}
}
Function toggle (){
Var sec = this. parentNode. nextSibling;
If (sec. className. indexOf (config. collapsedClass )! =-1 ){
Sec. className = sec. className. replace (''+ config. collapsedClass ,'');
This. firstChild. nodeValue = config. collapseLabel
} Else {
Sec. className + = ''+ config. collapsedClass;
This. firstChild. nodeValue = config. expandLabel
}
Return false;
}
}) (); Step 4: Name the variable and function.
Copy codeThe Code is as follows: var collapser = (function (){
Var config = {
IndicatorClass: 'collapsible ',
CollapsedClass: 'collapsed ',
CollapseLabel: 'collapse ',
ExpandLabel: 'expand'
}
Var sections = document. getElementsByTagName ('div ');
For (var I = 0, j = sections. length; I <j; I ++ ){
If (sections [I]. className. indexOf (config. indicatorClass )! =-1 ){
Sections [I]. className + = ''+ config. collapsedClass;
Var paragraph = document. createElement ('P ');
Var trigger = document. createElement ('A ');
Trigger. setAttribute ('href ','#');
Trigger. onclick = toggleSection;
Trigger. appendChild (document. createTextNode (config. expandLabel ));
Paragraph. appendChild (trigger );
Sections [I]. parentNode. insertBefore (paragraph, sections [I]);
}
}
Function toggleSection (){
Var section = this. parentNode. nextSibling;
If (section. className. indexOf (config. collapsedClass )! =-1 ){
Section. className = section. className. replace (''+ config. collapsedClass ,'');
This. firstChild. nodeValue = config. collapseLabel
} Else {
Section. className + = ''+ config. collapsedClass;
This. firstChild. nodeValue = config. expandLabel
}
Return false;
}
}) (); Step 5: add necessary comments
Copy codeThe Code is as follows: // Collapse and expand section of the page with a certain class
// Written by Christian Heilmann, 07/01/08
Var collapser = (function (){
// Configuration, change CSS class names and labels here
Var config = {
IndicatorClass: 'collapsible ',
CollapsedClass: 'collapsed ',
CollapseLabel: 'collapse ',
ExpandLabel: 'expand'
}
Var sections = document. getElementsByTagName ('div ');
For (var I = 0, j = sections. length; I <j; I ++ ){
If (sections [I]. className. indexOf (config. indicatorClass )! =-1 ){
Sections [I]. className + = ''+ config. collapsedClass;
Var paragraph = document. createElement ('P ');
Var trigger = document. createElement ('A ');
Trigger. setAttribute ('href ','#');
Trigger. onclick = toggleSection;
Trigger. appendChild (document. createTextNode (config. expandLabel ));
Paragraph. appendChild (trigger );
Sections [I]. parentNode. insertBefore (paragraph, sections [I]);
}
}
Function toggleSection (){
Var section = this. parentNode. nextSibling;
If (section. className. indexOf (config. collapsedClass )! =-1 ){
Section. className = section. className. replace (''+ config. collapsedClass ,'');
This. firstChild. nodeValue = config. collapseLabel
} Else {
Section. className + = ''+ config. collapsedClass;
This. firstChild. nodeValue = config. expandLabel
}
Return false;
}
})();