参考答案:
javascript
中的事件,可以理解就是在HTML
文档或者浏览器中发生的一种交互操作,使得网页具备互动性, 常见的有加载事件、鼠标事件、自定义事件等
由于DOM
是一个树结构,如果在父子节点绑定事件时候,当触发子节点的时候,就存在一个顺序问题,这就涉及到了事件流的概念
事件流都会经历三个阶段:
事件冒泡是一种从下往上的传播方式,由最具体的元素(触发节点)然后逐渐向上传播到最不具体的那个节点,也就是DOM
中最高层的父节点
1<!DOCTYPE html> 2<html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Event Bubbling</title> 6 </head> 7 <body> 8 <button id="clickMe">Click Me</button> 9 </body> 10</html>
然后,我们给button
和它的父元素,加入点击事件
1var button = document.getElementById('clickMe'); 2 3button.onclick = function() { 4 console.log('1.Button'); 5}; 6document.body.onclick = function() { 7 console.log('2.body'); 8}; 9document.onclick = function() { 10 console.log('3.document'); 11}; 12window.onclick = function() { 13 console.log('4.window'); 14};
点击按钮,输出如下
11.button 22.body 33.document 44.window
点击事件首先在button
元素上发生,然后逐级向上传播
事件捕获与事件冒泡相反,事件最开始由不太具体的节点最早接受事件, 而最具体的节点(触发节点)最后接受事件
事件模型可以分为三种:
事件绑定监听函数比较简单, 有两种方式:
1<input type="button" onclick="fun()">
JS
代码绑定1var btn = document.getElementById('.btn'); 2btn.onclick = fun;
DOM0
级事件具有很好的跨浏览器优势,会以最快的速度绑定,但由于绑定速度太快,可能页面还未完全加载出来,以至于事件可能无法正常运行
只支持冒泡,不支持捕获
同一个类型的事件只能绑定一次
1<input type="button" id="btn" onclick="fun1()"> 2 3var btn = document.getElementById('.btn'); 4btn.onclick = fun2;
如上,当希望为同一个元素绑定多个同类型事件的时候(上面的这个btn
元素绑定2个点击事件),是不被允许的,后绑定的事件会覆盖之前的事件
删除 DOM0
级事件处理程序只要将对应事件属性置为null
即可
1btn.onclick = null;
在该事件模型中,一次事件共有三个过程:
document
一直向下传播到目标元素, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行document
, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行事件绑定监听函数的方式如下:
addEventListener(eventType, handler, useCapture)
事件移除监听函数的方式如下:
removeEventListener(eventType, handler, useCapture)
参数如下:
eventType
指定事件类型(不要加on)handler
是事件处理函数useCapture
是一个boolean
用于指定是否在捕获阶段进行处理,一般设置为false
与IE浏览器保持一致举个例子:
1var btn = document.getElementById('.btn'); 2btn.addEventListener(‘click’, showMessage, false); 3btn.removeEventListener(‘click’, showMessage, false);
DOM
元素上绑定多个事件处理器,各自并不会冲突1btn.addEventListener(‘click’, showMessage1, false); 2btn.addEventListener(‘click’, showMessage2, false); 3btn.addEventListener(‘click’, showMessage3, false);
当第三个参数(useCapture
)设置为true
就在捕获过程中执行,反之在冒泡过程中执行处理函数
下面举个例子:
1<div id='div'> 2 <p id='p'> 3 <span id='span'>Click Me!</span> 4 </p > 5</div>
设置点击事件
1var div = document.getElementById('div'); 2var p = document.getElementById('p'); 3 4function onClickFn (event) { 5 var tagName = event.currentTarget.tagName; 6 var phase = event.eventPhase; 7 console.log(tagName, phase); 8} 9 10div.addEventListener('click', onClickFn, false); 11p.addEventListener('click', onClickFn, false);
上述使用了eventPhase
,返回一个代表当前执行阶段的整数值。1为捕获阶段、2为事件对象触发阶段、3为冒泡阶段
点击Click Me!
,输出如下
1P 3 2DIV 3
可以看到,p
和div
都是在冒泡阶段响应了事件,由于冒泡的特性,裹在里层的p
率先做出响应
如果把第三个参数都改为true
1div.addEventListener('click', onClickFn, true); 2p.addEventListener('click', onClickFn, true);
输出如下
1DIV 1 2P 1
两者都是在捕获阶段响应事件,所以div
比p
标签先做出响应
IE事件模型共有两个过程:
document
, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行事件绑定监听函数的方式如下:
attachEvent(eventType, handler)
事件移除监听函数的方式如下:
detachEvent(eventType, handler)
举个例子:
1var btn = document.getElementById('.btn'); 2btn.attachEvent(‘onclick’, showMessage); 3btn.detachEvent(‘onclick’, showMessage);
最近更新时间:2024-08-10