1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset=gb2312 />
5 <title>js</title>
6 <script>
7 //function语句在解析时会被提升,不管function语句放置在哪里,
8 //它都会被移动到所在作用域的顶层。
9 addEvent(window,'load',initAnchors);
10
11
12 function initAnchors(){
13 for(var i=1; i<=3; i++){
14 var anchor = $('anchor'+i);
15 registerListener(anchor,i); //函数中函数,也就是闭包,registerListener可以保存外部变量的值。
16 }
17 };
18 /*
19 把事件处理函数注册到一个独立的函数中。
20
21 现在click事件处理函数的外部作用域变成了registerListener()函数。
22
23 每次调用registerListener()函数时都会生成该函数的一个副本,
24 以维护正确的变量作用域。
25 */
26 function registerListener(anchor,i){
27 addEvent(anchor,'click',function(){
28 alert('my id is anchor'+i);
29 });
30 }
31 /*
32 因为i的值实际上是单击事件发生时才从作用域链中取得。
33 当单击事件必发生时,initAnchors()已经执行完毕(验证:在循环加入alert(i)后,打开网页会弹出三次框)。
34 此时i=4。所以alert会显示相同信息。
35
36 具体来说,当click事件处理函数被调用时,它会先在事件处理函数的内部作用域中查找i的值,
37 但click事件的匿名处理函数中没有定义i的值,所以它再到其外部作用域(initAnchors()函数)中查找。
38 而外部作用域中i=4。
39
40 function initAnchors(){
41 for(var i=1; i<=3; i++){
42 //alert(i);
43 var anchor = $('anchor'+i);
44 addEvent(anchor,'click',function(){
45 alert('my id is anchor'+i);
46 });
47 }
48 };
49
50 */
51 function addEvent( node, type, listener ) {
52 if (node.addEventListener) {
53 // W3C method
54 node.addEventListener( type, listener, false );
55 return true;
56 } else if(node.attachEvent) {
57 // MSIE method
58 //使用attachEvent()注册的回调函数没有Event参数,需要读取Window对象的event属性
59 //使用attachEvent()作为全局函数调用。而不是事件发生其上的文档元素的方法来调用
60 //也就是说attachEvent()注册的回调函数执行时,this指向window对象,而不是事件目标元素。
61 //下面修正这些问题
62 node['e'+type+listener] = listener;
63 node[type+listener] = function(){
64 node['e'+type+listener]( window.event );
65 }
66
67 //IE事件模型不支持事件捕获,所以需要两个参数
68 node.attachEvent( 'on'+type, node[type+listener] );
69
70
71 return true;
72 }
73
74 // Didn't have either so return false
75 return false;
76 };
77
78 function $() {
79 var elements = new Array();
80
81 // Find all the elements supplied as arguments
82 for (var i = 0; i < arguments.length; i++) {
83 var element = arguments[i];
84
85 // If the argument is a string assume it's an id
86 if (typeof element == 'string') {
87 element = document.getElementById(element);
88 }
89
90 // If only one argument was supplied, return the element immediately
91 if (arguments.length == 1) {
92 return element;
93 }
94
95 // Otherwise add it to the array
96 elements.push(element);
97 }
98
99 // Return the array of multiple requested elements
100 return elements;
101 };
102 </script>
103 </head>
104
105 <body>
106 <ul>
107 <li><a href="#" id="anchor1">Anchor 1</a></li>
108 <li><a href="#" id="anchor2">Anchor 2</a></li>
109 <li><a href="#" id="anchor3">Anchor 3</a></li>
110 </ul>
111
112 </body>
113 </html>