addEventListener和onclick
来源:互联网 发布:cx网络用语什么意思 编辑:程序博客网 时间:2024/06/16 16:47
在复习闭包的时候,我们知道,在为每一个子元素设置onclick事件时必须要加闭包,不然只有最后一个子元素加上了消息响应事件:
window.onload = function(){ var aLi = document.getElementsByTagName('li'); for (var i=0;i<aLi.length;i++){ (function(i){ aLi[i].onclick = function(){ alert(i); }; })(i); } };然而我自己写的子元素响应事件没有受影响
//为每一个tag添加监听事件function moveToDelete(){ var con=$('tag-box'); for(var i=0;i<con.childNodes.length;i++){ con.childNodes[i].addEventListener('mouseover',function(e){ var e=e||window.event; var ele= e.target; //console.log(ele); ele.style.background='blue'; ele.innerHTML="删除"+ele.innerHTML; }); con.childNodes[i].addEventListener('mouseout',function(e){ var e=e||window.event; var ele= e.target; ele.style.background='#d45d5c'; var s=ele.innerHTML.toString(); //取子串 ele.innerHTML= s.slice(2); }); con.childNodes[i].addEventListener('click',function(e){ var e=e||window.event; var ele= e.target; var index=parseInt(ele.getAttribute('data-index')); //删除 data1.splice(index,1); renderTag(); }); }}
首先说为啥要用闭包吧。找到一个讲解超详细的版本。
很高兴有一个纯JS的问题。
1,@杨咖啡 说的JS传参是传值不传址,其实不是这样的。JS中传参有两种方式:by value and by sharing.
像C,C++,Java,他们传参方式是by value 和 by reference。前者就是传值,后者是传址。而JS也是这样的,前者是传值,后者是传址。
By value是对于原始数据类型,例如int,char之类的;而By sharing 和By reference是对于高级数据结构,如Object,struct之类。我们可以想象到一个Object或是struct 不能仅仅通过传值进行传参。
一个简单的例子说明by reference和 by sharing的不同。
var bar;
var foo = bar;
bar = {'key' : 'value'};
console.log(foo , bar );
By sharing 中foo 是undefined , bar 是{'key' : 'value'}; 而By reference 则应该两者都是{'key' : 'value'}。
2. 其实LZ要理解这个问题,要明白JS中的作用域(scope)。
每个函数在创建完成时,他有3个重要的内置属性(property)也同时被创建。
{
AO //记录function内的变量,参数等信息
this // 就是在调用this.xx的时候的this
scope // 指向外层函数AO的一个链(在实现的时候,可能通过数组来实现).
}
JS中,大家经常讲的Scope其实是这样:SCOPE=AO+scope.
回到闭包的问题上:
如果我们这样写这个程序:
for(var i =0; i<link.length; i++){ //window scope
link[i].onclick = function(){ alert(i); }; // inner function
}
可以得到inner function的SCOPE是这样的:
{
AO
this // 等于link[i]
scope // 指向window的记录,包括我们需要的变量i
}
这个for循环会立即执行完毕,那么当onclick触发时,inner function查找变量 i 时,会在AO+scope中找,AO中没有,scope中的变量i已经成为了link.length.
利用大家所说的闭包写这个程序:
//here is the window scope
for(var i =0; i<link.length; i++){
link[i].onclick = (function(i){ // outer function
return function(){ //inner function
alert(i);
};
})(i);
}
分析inner function的SCOPE:
{
AO // no important infomation
this // we don't care it.
scope //outer function and window scope
}
outer function的SCOPE
{
AO // 包含参数i
this // don't care it .
scope // window scope.
}
这时,如果inner function被触发,他会从自己的AO以及scope(outer function的AO 和 window scope)中找寻变量i. 可以看到outer function的AO中已经包含了i,而且对于这个for循环,会有对应有N个(function(){})() 被创建执行。所以每个inner function都有一个特定的包含了变量 i 的outer function。
这样就可以顺利输出0,1,2,3。。。。。。。。。
结论: 我们可以看到,闭包其实就是因为Scope产生的,所以,广义上来讲,所有函数都是闭包。
另外,这里面也包含了,this, function expression 和function declaration的区别,这里就不一一讲了。
3. 另外一种方法:
利用 dom onclick事件的bubble特性,也就是@xiiiiiin所讲的弄个代理。
在link dom节点的父节点上定义onclick事件监听。参数为e(其他的名字也可以,但要有参数)。 这样我们通过e.target就可以知道是那个子节点被click了,也可以做相应的处理。
这是一个比较好的方法。(闭包有时会产生内存泄漏)。
1,@杨咖啡 说的JS传参是传值不传址,其实不是这样的。JS中传参有两种方式:by value and by sharing.
像C,C++,Java,他们传参方式是by value 和 by reference。前者就是传值,后者是传址。而JS也是这样的,前者是传值,后者是传址。
By value是对于原始数据类型,例如int,char之类的;而By sharing 和By reference是对于高级数据结构,如Object,struct之类。我们可以想象到一个Object或是struct 不能仅仅通过传值进行传参。
一个简单的例子说明by reference和 by sharing的不同。
var bar;
var foo = bar;
bar = {'key' : 'value'};
console.log(foo , bar );
By sharing 中foo 是undefined , bar 是{'key' : 'value'}; 而By reference 则应该两者都是{'key' : 'value'}。
2. 其实LZ要理解这个问题,要明白JS中的作用域(scope)。
每个函数在创建完成时,他有3个重要的内置属性(property)也同时被创建。
{
AO //记录function内的变量,参数等信息
this // 就是在调用this.xx的时候的this
scope // 指向外层函数AO的一个链(在实现的时候,可能通过数组来实现).
}
JS中,大家经常讲的Scope其实是这样:SCOPE=AO+scope.
回到闭包的问题上:
如果我们这样写这个程序:
for(var i =0; i<link.length; i++){ //window scope
link[i].onclick = function(){ alert(i); }; // inner function
}
可以得到inner function的SCOPE是这样的:
{
AO
this // 等于link[i]
scope // 指向window的记录,包括我们需要的变量i
}
这个for循环会立即执行完毕,那么当onclick触发时,inner function查找变量 i 时,会在AO+scope中找,AO中没有,scope中的变量i已经成为了link.length.
利用大家所说的闭包写这个程序:
//here is the window scope
for(var i =0; i<link.length; i++){
link[i].onclick = (function(i){ // outer function
return function(){ //inner function
alert(i);
};
})(i);
}
分析inner function的SCOPE:
{
AO // no important infomation
this // we don't care it.
scope //outer function and window scope
}
outer function的SCOPE
{
AO // 包含参数i
this // don't care it .
scope // window scope.
}
这时,如果inner function被触发,他会从自己的AO以及scope(outer function的AO 和 window scope)中找寻变量i. 可以看到outer function的AO中已经包含了i,而且对于这个for循环,会有对应有N个(function(){})() 被创建执行。所以每个inner function都有一个特定的包含了变量 i 的outer function。
这样就可以顺利输出0,1,2,3。。。。。。。。。
结论: 我们可以看到,闭包其实就是因为Scope产生的,所以,广义上来讲,所有函数都是闭包。
另外,这里面也包含了,this, function expression 和function declaration的区别,这里就不一一讲了。
3. 另外一种方法:
利用 dom onclick事件的bubble特性,也就是@xiiiiiin所讲的弄个代理。
在link dom节点的父节点上定义onclick事件监听。参数为e(其他的名字也可以,但要有参数)。 这样我们通过e.target就可以知道是那个子节点被click了,也可以做相应的处理。
这是一个比较好的方法。(闭包有时会产生内存泄漏)。
作者:杨志
链接:http://www.zhihu.com/question/20019257/answer/13688887
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
MDN https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
onclick来自dom0定义,addeventlistener来自dom2定义。
明天续
0 0
- addEventListener和onclick
- addEventListener和onclick的区别
- 前端事件处理addEventListener和onclick
- [JS] addEventListener和onclick的区别
- onclick vs addEventListener
- javascript中 addEventListener和attachEvent以及element.onclick的区别
- js事件绑定 onclick && addEventListener
- [前端][js]onclick or addEventListener
- [JavaScript]onclick、addEventListener、attachEvent详解
- addEventListener与onclick的比较
- JS: .onClick attachEvent和addEventListener三者面对不同浏览器的区别
- 事件处理中的this:attachEvent, addEventListener, onclick
- 原生js,onclick与addEventListener区别
- attachEvent和addEventListener
- attachEvent和addEventListener使用方法
- attachEvent和addEventListener 使用方法
- attachEvent和addEventListener
- attachEvent和addEventListener
- ZMY_补间动画
- Scala之旅-高阶函数
- java代码里获取xml文件里的数据库配置信息
- SQLite数据库的运用:
- 项目20--静态成员应用
- addEventListener和onclick
- xlistview用到的方法
- 源码阅读(一)
- 安装ubuntu-server版服务器系统
- 《机器学习(周志华)》 习题5.5答案
- 快速排序例程
- Tls 线程局部存储
- HYSBZ 2705
- LeetCode 64 - Minimum Path Sum