系统提供好的注册事件监听的方式
给元素添加事件的方式(三种)
-
行内添加事件 —
<div onclick="show()"></div>
(不推荐); -
属性绑定的方式 —添加事件:
ele.onclick=function(){}
有事件层叠覆盖问题 -
添加事件监听的方式 —
ele.addEventListener("不带on的事件名称",事件驱动函数,布尔值);
没有覆盖问题 -
添加事件监听的方式 —
元素对象.attachEvent("带on的事件名称",事件驱动函数)
-
自己封装的addEventListener() 所有浏览器都支持,但是: event对象不支持,事件驱动函数传参数不支持。
/*
传统添加事件的方式会有层叠覆盖问题(自己封装):
针对同一个元素如果多次添加同一种类型的事件,那么最后添加的事件会覆盖之前添加过的事件,导致功能丢失,那么该如何解决呢?
思路:
1. 再添加事件要覆盖以前的事件之前,先获取老事件,看看有没有
2. 如果有 则把老事件的代码拿过来 放到首位 然后再把我们这次要添加的事件代码放到后面,执行时,先执行老事件代码,再执行新事件代码。
*/
/*
步骤:
1. 先获取老事件
2. 判断有没有老事件
3. 如果有 则把老事件代码先保留
4. 再注册新事件
5. 在执行新事件之前把老事件的代码先执行
*/
// 参数: ele 元素对象 eventName(不带on的事件名称)
function addEventListener(ele,eventName,fn){
// 1.先获取老事件
var oldEvent=ele["on"+eventName];
//2.判断有没有老事件
if(oldEvent==null){
//表示没有老事件 就可以直接添加新事件 则直接绑定参数传进来的事件驱动函数
ele["on"+eventName]=fn;
}else{
//3.如果有 则把老事件代码先保留
ele["on"+eventName]=function () {// 4.再注册新事件
// 5.在执行新事件之前把老事件的代码先执行
oldEvent();
fn();
}
}
}
注册事件监听的兼容性问题
元素对象.onclick
: 几乎所有浏览器都支持;元素对象.addEventListener("不带on的事件名称",事件驱动函数,布尔值)
;
IE9+ 谷歌/火狐支持
IE8及以下不支持该方法
元素对象.attachEvent("带on的事件名称",事件驱动函数)
;
IE10及以下都可以使用 (IE678是反着来的 后添加的事件 先执行)
IE11/谷歌火狐 不支持该方法
.
添加事件的兼容性封装
兼容性封装,确定好 该方法 在不支持的浏览器里面返回什么,判断当前是什么浏览器
1. 元素对象.addEventListener()
谷歌/火狐/IE9+ 返回:完整的函数对象 —>有值
IE678返回: undefined
2. .元素对象.attachEvent()
谷歌/火狐/IE11+ 返回: undefined
IE6789/10 返回: 整个函数对象 —>有值
针对添加事件的兼容性封装
参数:
- ele 元素对象
- 不带on的事件名称
- 事件驱动函数
function addEvent(ele,eventName,fn) {
if(ele.addEventListener){
// 匹配到此处表示 谷歌/火狐/IE9+
ele.addEventListener(eventName,fn);
}else if(ele.attachEvent){
// IE678匹配到此处
ele.attachEvent("on"+eventName,fn);
}else{
//可以使用onclick 虽然不太可能匹配此处
//需要使用没有层叠覆盖问题的onclick
// 1.先获取老事件
var oldEvent=ele["on"+eventName];
//2.判断有没有老事件
if(oldEvent==null){
//表示没有老事件就可以直接添加新事件 则直接绑定参数传进来的事件驱动函数
ele["on"+eventName]=fn;
}else{
//3.如果有 则把老事件代码先保留
ele["on"+eventName]=function () {// 4.再注册新事件
// 5.在执行新事件之前把老事件的代码先执行
oldEvent();
fn();
}
}
}
}
addEventlistener和attachEvent的区别
- 事件名称的区别:
addEventLisener中第一个参数type是click、load,不带on
attachEvent中一个参数type是onclick、onload
- this的区别:
addEventLisener:事件处理程序会在当前对象的作用域运行,因此,时间处理程序的this就是当前对象。
attachEvent:事件处理程序是在全局作用域下运行因此this就是window。
事件解绑以及兼容性封装
用什么绑定的 就用什么解绑
- 元素.onclick绑定的
就用元素.onclick=null解绑
- 元素.addEventListener绑定的事件
就用元素.removeEventListener解绑
元素.removeEventListener("不带on的要解绑的事件名称",已经定义好有名字的那个驱动函数)
- .元素.attachEvent绑定的事件
就用元素.detachEvent()解绑
元素.detachEvent("带on的要解绑的事件名称,已经定义好有名字的那个驱动函数")
解绑事件的兼容性和绑定事件的 是一样的!
关于解绑事件的兼容性封装(第一版含有bug)
function removeEvent(ele,eventName,fn) {
if(ele.detachEvent!=undefined){
alert("准备用detachEvent解绑")
ele.detachEvent("on"+eventName,fn);
}else if(ele.removeEventListener!=undefined){
alert("准备用removeEventListener解绑")
ele.removeEventListener(eventName,fn);
}else{
alert("准备用οnclick=null解绑")
// 极其特殊才能执行到这
ele["on"+eventName]=null;
}
}
改进本解绑事件的封装(解决bug)
function removeEvent(ele,eventName,fn) {
// 先判断是否使用的onclick方式绑定的
if(ele["on"+eventName]){
// 执行到此处 表示 通过on绑定了一个事件
ele["on"+eventName]=null;
}else if(ele.detachEvent!=undefined){
ele.detachEvent("on"+eventName,fn);
}else {
ele.removeEventListener(eventName,fn);
}
}