(1) Code Description
Css section:
*{ margin: 0; padding: 0;} dl{ width: 300px; margin: 100px auto; border: #666 1px solid; border-bottom: none;} dt{ line-height: 40px; background: #888; color: #fff; font-size: 14px; font-weight: bold; padding-left: 20px; border-top: #999 1px solid; border-bottom: #666 1px solid; cursor: pointer;} dt.click{ background: #dfdfdf; color: #333; border-bottom: #cfcfcf 1px solid; border-top: #efefef 1px solid;} dd{ display:none; color: #444; font-size: 12px; text-align: center; padding: 20px; background: #efefef;} dd.block{ display: block; border-bottom:#666 1px solid; }
Script part (embedded in head ):
/* Obtain the dt and dd label groups respectively */var listContainer = document. getElementById ('listcontainer'), dts = document. getElementsByTagName ('dt'), dds = document. getElementsByTagName ('dd');/* (before changing the Class Name of the clicked dt, the adjacent dd changes the class name) Determines dt. click, dd. whether the block exists and sets the class name to null */function disappear () {for (var n = 0; n <dts. length; n ++) {if (dts [n]. className = 'click') {dts [n]. className = '';} if (dds [n]. className = 'block') {dds [n]. className = '';}}/ * main function --- used to hide the old Tab Display new tab */function clickEffects () {for (var I = 0; I <dts. length; I ++) {(function (num) {dts [num]. onclick = function () {disappear (); this. className = (this. className! = 'Click ')? 'Click': ''; dds [num]. className = (this. className! = 'Block ')? 'Block': '';}}) (I) ;}} window. onload = clickEffects;
Html section:
<Dl id = "listContainer"> <dt class = "click"> Title 1 </dt> <dd class = "block"> content 1 </dd> <dt> title II </dt> <dd> content 2 </dd> <dt> Title 3 </dt> <dd> content 3 </dd> <dt> Title 4 </dt> <dd> content 4 </dd> </dl>
(2) important knowledge points:
The core function of this script is clickEffects. Its main function is to add a click event for dt.
The event implementation process consists of two steps: Step 1-determine dt. click, dd. whether clock exists. If clock exists, set the class name to null. Step 2 --- add the dt label of the current click and the adjacent dd label to the class name (. click ,. block ).
There are two knowledge points in this core function:
First, create and execute anonymous functions.
The format for creating an anonymous function is function (){}.
The execution format of anonymous functions is: (function (arg) {}) (x) arg is the parameter, and x is the reference variable of the value or value passed to the parameter. Because an anonymous function does not have a function name, that is, it does not reference one of its names. Therefore, it cannot be executed like functionName (). Therefore, the brackets expression must act as functionName. The parentheses outside function () are actually used to evaluate the value. After the content is evaluated, a function is returned. Therefore, you need to add a parentheses to execute the function. In addition, this format applies to functions referenced by variable names, such as (function plus (x, y) {alert (x + y ). In short, parentheses outside the function cannot be lost. As in the above Code, "(function (num) {……}) in the function ){......}) () "Is a typical anonymous function self-execution.
Second: closure. A closure is a function within a function. Its feature is that it can access variables defined in a function.
In the above Code, the function bound to onclick generates a closure for its letter of guarantee function (self-executed anonymous function), and the anonymous function is executed completely, the local variable num is not recycled, but is still stored in the memory. Because the onclick function has not yet been executed, the num in this function still maintains a reference to the value corresponding to the num in the memory (that is, each I value of the for time ). In fact,:
for(var i=0;i<dts.length;i++){ (function(num){ dts[num].onclick=function(){ disappear(); this.className= (this.className!=='click')? 'click':''; dds[num].className= (this.className!=='block')? 'block':''; } })(i);
(The value of dts. length is 3) We can understand:
After four anonymous functions are executed, clickEffects returns the result. These four anonymous functions are independent, namely:
Function (0) {dts [0]. onclick = function (){...... dts [0]. className = ......}} (0 );
Function (1) {dts [1]. onclick = function (){...... dts [1]. className = ......}} (1 );
Function (2) {dts [2]. onclick = function (){...... dts [2]. className = ......}} (2 );
Function (3) {dts [3]. onclick = function (){...... dts [3]. className = ......}} (3 );
For better understanding, we can call these anonymous functions A, B, C, and D.
Therefore, when the onclick function in A is executed, the variable num is found in the scope of its contained function A and the value is 0 (because A is executed immediately, therefore, after the execution is complete and the return value is 0 );
Similarly, B, C, and D.
Closure is a very important part of js, and it is closely related to the scope chain and activity objects. For more information, see:
Http://coolshell.cn/articles/6731.html
Http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
Or the description of closures in javascript advanced programming.
In this example, the function bound to the click event is a typical closure. It is also because of the existence of closures that anonymous function self-execution is used to achieve the effect of tabs.