# 移除事件与 bind
# addEventListener()
添加监听事件
语法
obj.addEventListener(type, listener[, useCapture])
obj.addEventListener(type, listener [,{capture: Boolean, once: Boolean, passive: Boolean}])
obj
需要添加的事件的对象 必须是对象节点
type
需要监听的事件类型
listener
需要监听的
EventListener
函数 必须和removeEventListener
绑定的事件内存保持一致 否则移除不了useCapture
布尔值 默认是
false
指事件句柄处于捕获阶段capture
布尔值 默认是
false
指事件句柄处于捕获阶段 如果设置为true
不管bubbling
设置什么都会变为冒泡阶段once
布尔值,默认是
false
事件会多次触发 如果想触发一次可以变为true
-
布尔值,默认是
true
代表该监听器内部不会调用preventDefault
函数来阻止默认滑动行为 事件设置冒泡阶段
var baba = document.querySelector(".baba"), son = document.querySelector(".son"); baba.addEventListener("click",function(){ console.log("baba") },true) son.addEventListener("click",function(){ console.log("son") })
1
2
3
4
5
6
7
8绑定一次事件
document.querySelector(".baba").addEventListener("click",function(){ console.log("baba") },{ once:true })
1
2
3
4
5
# removeEventListener()
移除监听事件
语法
obj.removeEventListener(type, listener[, useCapture])
obj
需要移除的事件的对象 必须是对象节点
type
需要移除的事件类型
listener
需要移除的
EventListener
函数 必须和addEventListener
绑定的事件内存保持一致 否则移除不了useCapture
布尔值 默认是
false
指事件句柄处于捕获阶段事件不执行,直接移除
var btn = document.querySelector("button"); btn.addEventListener("click", say); btn.removeEventListener("click", say); function say() { console.log(btn.classList); }
1
2
3
4
5
6事件执行一次后直接移除
var btn = document.querySelector("button"); btn.addEventListener("click", say); function say() { console.log(btn.classList); btn.removeEventListener("click", say); }
1
2
3
4
5
6
# bind()
绑定事件
语法
fun.bind(thisArg[, arg1[, arg2[, ...]]])
fun
fun
只能是函数名 不能写成function say(){}.bind()
thisArg
当绑定函数被调用时 该参数会作为原函数运行时的
this
指向(也就是this
放生了改变 并且当遇到new
操作符时会失效)arg1, arg2, ...
当绑定函数被调用时 这些参数将置于实参传递给之前被绑定的方法作为形参
btn.addEventListener("click",function(color,bg_color){ this.style.color = color; this.style.bgColor = bg_color; }.bind(div,"red","blue"))
1
2
3
4描述
在使用
bind()
方法时是创建一个新函数(称为绑定函数) 相当于是被调函数的拷贝当新函数被调用时
this
值是bind()
的第一个参数 该参数不能被重写正是因为
bind()
方法使用时会拷贝新的函数 所以会让removeEventListener()
失效 因为内存指向不一致var h1 = document.querySelector("h1"), btn = document.querySelector("button"), num = 0; btn.addEventListener("click", change_color.bind(h1)); function change_color() { ++num % 2 ? this.style.color = "blue" : this.style.color = "red"; console.log(num); btn.removeEventListener("click", change_color.bind(h1)); }
1
2
3
4
5
6
7
8
9在上面的例子中要确保移除
click
事件就必须保证change_color
指向同一个内存地址.var h1 = document.querySelector("h1"), btn = document.querySelector("button"), my_color_fun = change_color.bind(h1), num = 0; btn.addEventListener("click", my_color_fun); function change_color() { ++num % 2 ? this.style.color = "blue" : this.style.color = "red"; console.log(num); btn.removeEventListener("click", my_color_fun); }
1
2
3
4
5
6
7
8
9
10可以通过
onclick
和addEventListener()
的区别来清除监听事件.var h1 = document.querySelector("h1"), btn = document.querySelector("button"), num = 0; btn.onclick = function() { ++num % 2 ? this.style.color = "blue" : this.style.color = "red"; console.log(num); btn.onclick = null; }.bind(h1)
1
2
3
4
5
6
7
8
# passive属性
什么是被动事件侦听器?
被动事件侦听器是一种新兴的网络标准 是
Chrome 51
附带的一项新功能 通过消除滚动以阻止触摸和滚轮事件监听器的需要 开发人员可以选择加入以提高滚动性能当我们通过事件调用
preventDefault()
来完全阻止滚动在事件时会报[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive (opens new window)
禁止用户通过滚轮缩放页面的解决方案
Passive Event Listeners
特性当前仅支持touch
和wheel
相关
document.addEventListener("wheel", function(e) { if (e.ctrlKey) { e.preventDefault(); } },{ passive:false })
1
2
3
4
5
6
7
# 总结
如果同一个对象分别为冒泡和捕获都添加了监听事件 那么这两次事件需要分别移除.两者不会互相干扰
bind()
方法会拷贝原函数一份 而不是直接用原函数进行操作addEventListener()
和removeEventListener()
的对象 触发事件 执行函数的内存地址必须一致 否则清除不到addEventListener()
可以给对象注册一个或多个同类型的监听事件而onclick
则是或者覆盖前者addEventListener()
可以更加精确的控制事件触发的阶段(冒泡或者捕获) 而onclick
只能是捕获阶段addEventListener()
对所有的DOM元素都有效果 而onclick
只能对HTML元素有效addEventListener()
添加监听事件时 会让this发生改变addEventListener()
添加监听事件时可以通过once
绑定一次事件
# 面试问题
案例一
this.age = 9; var melon = { age: 81, get_age: function () { return this.age; } }; melon.get_age(); //问题一 var get_age1 = melon.get_age; get_age1(); //问题二 var get_age2 = get_age1.bind(melon); get_age2(); //问题三
1
2
3
4
5
6
7
8
9
10
11
12案例二
function add(a, b) { return a + b; } var a = 3, b = 4, newFoo = add.bind(this, a, b); //问题一 a = 6; b = 7; newFoo(); //问题二
1
2
3
4
5
6
7
8
9