1 注册事件(绑定事件)
1.1 注册事件概述
给元素添加事件,称为注册事件或者绑定事件。注册事件有两种方式:传统方式和方法监听注册方式
传统注册方式
- 利用on开头的事件,eg:onclick,
<button onclick="alert('hi~')"></button>//传统方式1
btn.onclick = function(){}//传统方式2
- 特点:注册事件的唯一性,即同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的处理函数
方法监听注册方式
- w3c标准的推荐方式,利用addEventListener()方法实现
- IE9之前的IE不支持此方法,可以使用attachEvent()代替
- 特点:同一个元素同一个事件可以注册多个监听器,会按照注册顺序依次执行,不会有唯一性的问题
1.2 addEventListener 事件监听方式(ie9之后)
eventTarget.addEventListener(type, listener[, useCapture])//将指定的监听器(函数)注册到目标对象(eventTarget)上,当该对象触发指定事件时,就会执行事件处理函数。
- type:事件类型,该参数是字符串,比如:click、mouseover,注意这里不要带on
- listener:事件处理函数,事件发生时,会调用该监听函数
- userCapture:可选参数,是一个布尔值,默认是false。
1.3 attachEvent 事件监听方式(ie9以前)
该特性非标准,不要在生成环境中使用。该特性仅仅作为了解即可。只有ie浏览器可以识别,而且一定要ie9以前的浏览器。
eventTarget.attachEvent(eventNameWithOn, callback)//将指定的监听器(函数)注册到目标对象(eventTarget)上,当该对象触发指定的事件,指定的回调函数就会被执行。
- eventNameWithOn:事件类型,该参数是字符串,比如onclick、onmouseover,注意这里要带on
- callback:事件处理函数,当目标触发事件时回调函数被调用
以上3种方法举例
<body>
<button>传统注册事件</button>
<button>方法监听注册事件</button>
<button>ie9 attachEvent</button>
<script>
var btns = document.querySelectorAll('button');
//1. 传统方式注册事件
btns[0].onclick = function() {
alert('hi~');
}
btns[0].onclick = function() {
alert('hao a u~');
} //点击按钮后只会出现hao a u ~,前面的hi~被覆盖掉了,传统方法注册事件具有唯一性
//2. 事件监听注册事件
btns[1].addEventListener('click', function() {
alert('22');
})
btns[1].addEventListener('click', function() {
alert('33');
}) //点击按钮后会先后弹出对话框22和33,后面的函数不会覆盖前面的函数
//3. attachEvent ie9以前版本支持
btns[2].attachEvent('onclick', function() {
alert(11);
})
</script>
</body>
1.4 兼容性处理方案(了解)
2 删除事件(解绑事件)
2.1 删除事件的方式
传统解绑事件方式
eventTarget.onclick = null;
方法监听解绑事件的方式
eventTarget.removeEventListener(type, listener[, useCapture]);
方法监听解绑事件的方式(仅适用于ie678)
eventTarget.detachEvent(eventNameWithOn, callback)
以上三种方法举例
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<script>
var divs = document.querySelectorAll('div');
//1. 传统方式解绑事件
divs[0].onclick = function() { //点击第一个div盒子弹出一次11,之后再点第一个div盒子就不会弹出任何内容了
alert(11);
divs[0].onclick = null;
}
//2. 方法监听解绑事件的方式
divs[1].addEventListener('click', fn) //考虑到接下来要移除,则不能采取匿名函数的方法,而且只要写一个函数名fn就可以了,不用加小括号fn()
function fn() {
alert(22);
divs[1].removeEventListener('click', fn);
}
//3. 专门针对于ie678的解绑方式
divs[2].attachEvent('onclick', fn1);
function fn1() {
alert(33);
divs[2].detachEvent('onclick', fn1);
}
</script>
</body>
2.2 删除事件兼容性问题解决方案(了解)
3 DOM事件流
- 事件流:事件发生时会在元素节点之间按照特定的的顺序传播,这个传播过程即为DOM事件流
- 事件流理解
注意
- JS代码中只能执行捕获或者冒泡其中的一个阶段
- onclick和attachEvent只能得到冒泡阶段
- addEventListener(type,listener[,useCapture])第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(不写就默认是false),表示在事件冒泡阶段调用事件处理程序。
- 实际开发中很少使用事件捕获,更关注事件冒泡
-
有些事件是没有冒泡的,比如:onblur、onfocus、onmouseenter、onmouseleava
捕获
<body>
<div class="father">
<div class="son">son盒子</div>
</div>
<script>
//dom事件流三个阶段
//1. JS代码中只能执行捕获或者冒泡其中一个阶段。
//2. onclick和attachEvent(ie)只能得到冒泡阶段
//3. addEventListener【第三个参数是true】 捕获阶段:document->html->body->father->son 从上到下依次检测是否添加了点击事件,若添加了则依次执行,所有将先弹出father,再弹出son
var son = document.querySelector('.son');
son.addEventListener('click', function() {
alert('son');
}, true);
var father = document.querySelector('.father');
father.addEventListener('click', function() {
alert('father');
}, true);
</script>
</body>
冒泡
<body>
<div class="father">
<div class="son">son盒子</div>
</div>
<script>
//dom事件流三个阶段
//1. JS代码中只能执行捕获或者冒泡其中一个阶段。
//2. onclick和attachEvent(ie)只能得到冒泡阶段
//4. addEventListener【第三个参数是false或省略】 冒泡阶段:document<-html<-body<-father<-son 从下到上依次检测是否添加了点击事件,若添加了则依次执行,所有将先弹出son,再弹出father
var son = document.querySelector('.son');
son.addEventListener('click', function() {
alert('son');
}, false);
var father = document.querySelector('.father');
father.addEventListener('click', function() {
alert('father');
}, false);
</script>
</body>