DOM事件&事件绑定
事件
事件是浏览器默认具备的行为,不论是否基于JS绑定方法,事件都是存在的。只要相关的行为触发( 比如点击 ),相关的事件( 点击事件 ) 就会触发。
给元素绑定点击事件的说法是不严谨的,
严谨的说法应该是给元素的点击事件行为绑定方法。
即:⬇
事件绑定
给元素的事件行为绑定方法,当事件触发时,方法执行。
DOM0级事件绑定
- 语法:
元素.onxxx = function(){}
- 原理:给当前元素对象的某些私有属性赋值一个函数。
- 当我们在控制台输出某个元素对象时,可以查看这些属性。事件行为触发时,浏览器JS引擎会帮助我们把方法执行。
- 移除绑定:
元素.onxxx = null
,让这个属性指向一个空对象。 - DOM0级事件绑定的局限性:
- 由于事件作为私有属性存在,因此只能给当前元素的某个事件行为绑定一个方法,如果绑定多个则后面的会将前面的替换掉。
- 有些事件在元素的私有属性里是不存在的,无法给这些事件绑定方法。
- 当我们在控制台输出某个元素对象时,可以查看这些属性。事件行为触发时,浏览器JS引擎会帮助我们把方法执行。
DOM2级事件绑定
-
语法:
- 标准浏览器中:
元素.addEventListener('xxx',function(){},[false/true])
,[]可选参数,默认为false( 在冒泡阶段执行 ) - IE6~8中:
元素.attachEvent('onxxx',function(){})
- 标准浏览器中:
-
原理:基于元素的原型链__proto__找到EventTarget.prototype,使用内置的addEventListener和removeEventListener进行事件绑定 / 移除绑定(在不考虑兼容性的情况下)。
-
底层原理:基于浏览器内置的事件池机制完成事件监听&方法绑定。
- 事件池( 事件队列 )示意图如下:
元素 事件类型 方法 传播方式 box click fn1 … box click fn2 … box mouseenter fn1 … … … … … addEventListener
方法会向事件池中添加内容,在每次存储前作去重处理(不能完全重复)。
例如触发了box元素的click事件,会从事件池中把所有box元素的click事件绑定的方法全部找出来,然后依次执行。- 移除绑定:
元素.removeEventListener('xxx',function(){})
需要注意:移除绑定时传递的参数( 即元素和方法 ) 都要与绑定时的一毛一样——方法所在的函数堆地址不一样也不行!!!因此,为了方便移除,一般不会绑定匿名方法,而是绑定具名方法(移除时只要把方法名写上就行了,可以保证是同一个方法)。 - 相对于DOM0级事件绑定的优势:
- 可以给当前元素的某个事件绑定多个不同的方法,触发的时候依次执行即可。
- 所有浏览器支持的事件类型都可以绑定。
浏览器支持的事件可查看MDN文档:事件参考|MDN