js事件
事件
var div = document.getElementsByClassName('name');
div.onclick = function(){
console.log("hello world");
}
但是一个对象只能有一个onclick 事件,下面的会覆盖上面的
<div style="width: 100px;height: 100px;background-color:red" onclick = "console.log("hello world");"></div>
行间不用写function
句柄写法
addEventListener
div.addEventListener('事件类型',处理函数,false);
div.addEventListener('click',function(){
console.log("hello world");
},false);
可以给一个对象的一个事件绑定多个处理函数
按照绑定的顺序执行
attachEvent
IE独有的,一个事件同样绑定多个处理程序
div.attachEvent('on' + type fn);
div.attachEvent('on'+ 事件类型,处理函数);
div.attachEvent('onClick',function(){
});
闭包问题
绑定事件一定要注意,事件是否出现到循环里面,如果有就要考虑是否使用立即执行函数来处理闭包问题。
事件处理程序的运行环境
1. ele.onXXX = function(event){
console.log(this);
}
//程序this指向的是dom元素本身
2. obj.addEventListener(type,fn,false){
}
//程序this指向的是dom元素本身
3.obj.attachEvent('on'+type,fn){
}
//程序this指向的是window
封装兼容性
function addEventListen (elem, type, handle){
if (elem.addEventListener) {
elem.addEventListener(type,handle,false);
console.log("This is CHrome");
}else if(elem.attachEvent){
elem.addachEvent('on'+type,function(e){
handle.call(elem);
});
console.log("This is IE");
}else{
elem['on'+type] = handle;
}
}
var click = "click";
var div = document.getElementsByTagName('div')[0];
addEventListen(div,click,function(e){
div.style.backgroundColor = "red";
})
解除事件处理函数
ele.onclick = false/''/null;
ele.removeEventListener(type,fn,false);
ele.detachEvent('on' + type, fn);
若绑定匿名函数,则无法解除;
事件处理模型 - 事件冒泡,捕获
一个对象的的一个事件类型,只能是一种事件处理模型,要么是事件冒泡,要么是事件捕获.
-
事件冒泡
结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素(自底向上)
//事件冒泡
var wrapper = document.getElementsByClassName('wrapper')[0]; var content = document.getElementsByClassName('content')[0]; var box = document.getElementsByClassName('box')[0]; wrapper.addEventListener('click',function(){ console.log("wrapper"); },false); content.addEventListener('click',function(){ console.log("content"); },false); box.addEventListener('click',function(){ console.log("box"); },false);
-
事件捕获
结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自顶向下)
box.addEventListener('click',function(){console.log("box");
},false);
将 false 改为 true 就是事件捕获模型
面试中可能会问到其他的事件捕获:
IE独有 ele.setCapture();会将页面中任何事件捕获到ele上.ele.releaseCapture();释放 -
触发顺序,先捕获,后冒泡 但是会存在事件真实执行,执行在捕获前面
-
focus, blur, change, submit, reset, select 等事件不冒泡
取消冒泡和阻止默认事件
-
取消冒泡
- W3C 标准event.stopPropagation();但是不支持ie9以下的版本.
- IE独有 event.cancelBubble = true;
3.封装取消冒泡的函数stopBubble(event)
function stopBubble(e){
if(e && e.stopPropagation){
e.stopPropagation();
}else{
e.cancelBubble = true;
}
}
-
阻止默认事件
. 默认事件 - 表单提交,a标签跳转,右键菜单###
- return false 以对象属性的方式注册的事件才能生效.
- event.preventDefault(),W3C标注,IE9以下不兼容
3.event.returnValue = false ;兼容IE
封装阻止默认事件的函数 cancelHandler(event)
鼠标事件
- click, mousedown, mousemove, mouseup,contextmenu, mouseover, mouseout,mouseenter,mouseleave.
- 用button来区分鼠标的按键,0/1/2
- DOM3标准规定:click事件只能监听左键,只能通过mousedown和mouseup来判断鼠标键.
如何解决mousedown和click的冲突
键盘事件
keydown keypress keyup
keydown 除了fn 都可以监控到,不好监控字符类按键,
keypress 只是可以监听 字符类按键,区分大小写
事件委托
让利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行!
事件委托机制?这样做有什么好处?
- 事件委托,就是某个事件本来该自己干的,但是自己不干,交给别人来干,就叫事件委托。打个比方:一个button对象,本来自己需要监控自身的点击事件,但是自己不来监控这个点击事件,让自己的父节点来监控自己的点击事件。
好处:
- 提高性能:例如,当有很多li同时需要注册时间的时候,如果使用传统方法来注册事件的话,需要给每一个li注册事件。然而如果使用委托事件的话,就只需要将事件委托给该一个元素即可。这样就能提高性能
- 新添加的元素还会有之前的事件
遇到挫败,要学会左手温暖右手,相信明天会更好,after all,tomorrow is another day,满怀希望的活下去,不放弃学习,不放弃努力,forever youthful,forever weeping!!