zoukankan      html  css  js  c++  java
  • 动态绑定事件的方法

    <!doctype html>
    <html>
    <head>
    	<meta charset = "utf-8" />
    </head>
    
    	<div id = "target"></div>
    	<script>
    		var div = document.getElementById("target");
    		for(var i = 0; i < 8; i++){
    			var p = document.createElement("p");
    			var b = document.createElement("button");
    			b.innerText = "button" + i;
    			div.appendChild(b);
    			div.appendChild(p);
    			
    			b.onclick = function(){
    				p.innerText = i;
    			}
    			
    		}	
    	</script>
    </body>
    
    </html>
    

      上面代码原意是希望将生成的button元素,绑定相对应的p元素,但是运行后发现所有的button元素都绑定了最后一个p元素。

           为什么?

           这是因为onclick事件绑定的函数的词法环境(作用域)都是for循环花括号区域,区域中有p,b,i三个变量。

           而b.onclick = function(){}和这个作用域形成了闭包,函数中使用该作用域的p,i变量,造成所有绑定事件共享这两个变量。

           在页面加载后,所有button 未被点击前,for循环已经结束。作用域变量变为i = 8, p => 最后一个p。

           一触发onclick事件,调用function(){p.innerText = i;},就变成了最后一个p元素显示文本8。

           这十分像java的继承,触发一次onclick就是一次“继承”,然后共用父类的成员变量, p,b是“protected类型”。 

          闭包的参考:   https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures

          所以,在公共的作用域for循环没有结束前立刻保存每一次循环的p和i是十分必要的。

          考虑用参数传递的方式将每次的p和q传递到function(){p.innerText = i;}中,则有:

      function test(p,i){p.innerText = i;}

           立刻触发事件传递参数: test(p,i);     

           又onclick需要绑定一个函数,但是b.onclick = function(){}的写法在触发时不能同时绑定。故让test函数内部返回一个操作函数,test函数作为直接的绑定。

      b.onclick = function test (p,i){ 

                return function(){

                         p.innerText = i;

              }

           }     

          test (p,i);


          这样就间接绑定了操作,也传递了参数。

     使用匿名函数可以将代码合并:

     

    b.onclick = (function(p,i){
    	return function(){
    		p.innerText = i;
    	}
    })(p,i);
    

      以上代码可以实现效果。

      除了闭包外,还可以使用let来处理。

      let定义函数变量有各自的块作用域,可以保证onclick事件的词法环境中let定义的变量的不同的。

      代码可改为:

      

    var div = document.getElementById("target");
    for(let i = 0; i < 8; i++){
    	let p = document.createElement("p");
    	var b = document.createElement("button");
    	b.innerText = "button" + i;
    	div.appendChild(b);
    	div.appendChild(p);
    			
    	b.onclick = function(){
    		p.innerText = i;
    	}
    }
    

      

     

       

            

          

  • 相关阅读:
    Windows 7 远程协助
    Windows 7 帮助和支持资源—第三方网站
    Windows 7 帮助和支持资源—第三方软件
    数据结构-队列
    数据结构-栈
    pycharm每日技巧-2
    数据结构-链表
    时间处理-1
    二维数组的排序
    《疯狂的简洁》书摘
  • 原文地址:https://www.cnblogs.com/githubMYL/p/8629915.html
Copyright © 2011-2022 走看看