何为 DOM 事件,HTML DOM 使JavaScript 有能力对 HTML 事件做出反应。

1. 事件流

一个 DOM 事件可以分为捕获过程触发过程冒泡过程

下面一个<a>元素被点击为例。

  1. 红虚线:捕获过程。当DOM事件发生时,它会从window节点一路跑下去直到触发事件元素的父节点为止,去捕获触发事件的元素。
  2. 红绿实线:触发过程。当事件被捕获之后就开始执行事件绑定的代码。
  3. 绿虚线:冒泡过程。当事件代码执行完毕后,浏览器会从触发事件元素的父节点开始一直冒泡到window元素(即元素的祖先元素也会触发这个元素所触发的事件)。

看一个例子。

<!DOCTYPE html>
<html>
<head>
<style></style>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
$(function(){
// 捕获过程
document.addEventListener('click',function(){
console.log('capture:'+1);
},true);
var tableNode = document.getElementsByTagName('table')[0];
tableNode.addEventListener('click',function(){
console.log('capture:'+2);
},true);
var tdNode = tableNode.getElementsByTagName('td');
for(let i = 0, tdlength = tdNode.length; i < tdlength; i++){
tdNode[i].addEventListener('click',function(){
console.log('capture:'+3);
},true);
} // 冒泡事件
document.addEventListener('click',function(){
console.log('bubble:'+1);
});
tableNode.addEventListener('click',function(){
console.log('bubble:'+2);
});
for(let i = 0, tdlength = tdNode.length; i < tdlength; i++){
tdNode[i].addEventListener('click',function(){
console.log('bubble:'+3);
},true);
}
});
</script>
</head>
<body>
<table>
<tbody>
<tr>
<td>Grove</td>
<td>Aeolian</td>
</tr>
<tr>
<td>Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
</body>
</html>



每次点击td时触发点击事件,并执行代码console.log('...')

DOM规范规定,同一节点同一阶段的事件应按照注册函数的顺序执行。

2. 事件注册

2.1 注册事件

eventTarget.addEventListener(type, listener[,useCapture])
  • evenTarget表示要绑定事件的DOM元素。
  • type表示要绑定的事件。
  • listener表示要绑定的函数。
  • useCapture可选参数,表示是否捕获过程。

useCapture为设定是否为捕获过程,默认事件均为冒泡过程,只有useCapturetrue时才会启用捕获过程。

var tableNode = document.getElementsByTagName('table')[0];
// 注册事件
tableNode.addEventListener('click',function(){
console.log('capture:'+2);
},true);
var tableNode = document.getElementsByTagName('table')[0];
// 注册事件
tableNode.addEventListener('click', clickHandler,true);
var clickHandler = function(event) {
console.log('capture:'+2);
};
<!DOCTYPE html>
<html>
<head>
<style></style>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
$(function(){
var div = document.getElementsByTagName('div')[0];
//div.onclick = clickHandler;
// 注册事件的第二种方式,不推荐使用。
div.onclick = function(){
clickHandler();
foo();
// 其他处理函数
}; function clickHandler(){
console.log('clickHandler');
} function foo(){
console.log('foo');
}
});
</script>
</head>
<body>
<div>Hello</div>
</body>
</html>

2.2 取消事件

eventTarget.removeEventListener(type, listener[,useCapture]);
  • evenTarget表示要绑定事件的DOM元素。
  • type表示要绑定的事件。
  • listener表示要绑定的函数。
  • useCapture可选参数,表示是否捕获过程。

相关阅读:HTML DOM removeEventListener() 方法 | 菜鸟教程

2.3 触发事件

点击元素,按下按键均会触发 DOM 事件,当然也可以以通过代码来触发事件。

看一个例子。

<form>
<textarea></textarea>
</form>
const form = document.querySelector('form');
const textarea = document.querySelector('textarea'); const eventAwesome = new CustomEvent('awesome', {
bubbles: true,
detail: { text: () => textarea.value }
}); form.addEventListener('awesome', function(e){
console.log(e.detail.text());
}); textarea.addEventListener('input', function(e){
e.target.dispatchEvent(eventAwesome);
});



相关阅读:Creating and triggering events - Developer guides | MDN

3. 事件对象

调用事件处理函数时传入的信息对象,这个对象中含有关于这个事件的详细状态和信息,它就是事件对象event。其中可能包含鼠标的位置,键盘信息等。

<!DOCTYPE html>
<html>
<head>
<style></style>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
function whichButton(event){
var btnNum = event.button;
if (btnNum==2){
console.log("您点击了鼠标右键!")
} else if(btnNum==0){
console.log("您点击了鼠标左键!")
} else if(btnNum==1){
console.log("您点击了鼠标中键!");
} else{
console.log("您点击了" + btnNum + "号键,我不能确定它的名称。");
}
}
</script>
</head>
<body onmousedown="whichButton(event)">
<p>请在文档中点击鼠标。一个消息框会提示出您点击了哪个鼠标按键。</p>
</body>
</html>

相关阅读:HTML DOM Event 对象

事件对象event的方法:

  • stopPropagation:阻止事件冒泡传播
  • stopImmediatePropagation:阻止冒泡传播
  • preventDefault:阻止默认行为

event.stopPropagation():如果在当前节点已处理事件,则阻止事件被冒泡传播至 DOM 树最顶端即window对象。

event.stopImmediatePropagation():除了阻止将事件冒泡传播至window对象外,还会阻止在此事件后的事件的触发。

默认行为是指浏览器定义的默认行为(点击一个链接时,链接默认就会打开;双击文字的时候,文字就会被选中)。

4. 事件分类

<!DOCTYPE html>
<html>
<head>
<style></style>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
function foo(event){
console.log(event);
}
</script>
</head>
<body onmousedown="foo(event)">
<p>Click somewhere in the document.</p>
</body>
</html>

  • Event

    • UIEvent

      • FocusEvent
      • InputEvent
      • KeyboardEvent
      • MouseEvent
        • WheelEvent

5. 事件代理

事件代理是指在父节点上(可为元素最近的父节点也可为上层的其他节点)处理子元素上触发的事件,其原理是通过事件流机制而完成的。可以通过事件对象中获取到触发事件的对象(如下所示)。

<!DOCTYPE html>
<html>
<head>
<style></style>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
$(function(){
document.getElementById('list').addEventListener('click', function (e) {
// 兼容性处理
var event = e || window.event;
var target = event.target || event.srcElement;
console.log(target);
// 判断是否匹配目标元素
if (target.nodeName.toLocaleLowerCase() == 'li') {
console.log(target.innerHTML);
}
});
});
</script>
</head>
<body>
<ul id="list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
</ul>
</body>
</html>

注意:注册事件时addEventListener需要包含在$(function(){})里面,否则报错。

相关阅读:$(document).ready和window.onload的区别

参考:

最新文章

  1. 解决跑twoBitToFa时出现“/admin/exe/linux.x86_64/twoBitToFa: Permission denied”的问题
  2. 15个Linux Wget下载实例终极指南
  3. 汇文Libsys图书管理系统全版本权限绕过+getshell
  4. 小记:xml画一个爱心。
  5. Codeforces Round #131 (Div. 2)
  6. [Everyday Mathematics]20150129
  7. POJ 2774 最长公共子串
  8. java笔记12之面向对象初始
  9. Codeforces Round 371 Div2 B.Passwords
  10. javascript的介绍,实现和输出以及语法-javascript学习之旅(1)
  11. Linux内存管理 (26)内存相关工具
  12. Android的ViewPager的学习
  13. Raft 基础
  14. nginx配置虚拟机
  15. C#弹出窗体、C#导出Excel、C#数据展示框、C#弹出框
  16. Mysql41道练习题
  17. web压力测试工具(小而精)
  18. 学习 Flask 扩展 Flask-RESTful
  19. mysql打印输出转csv格式
  20. SQL on Hadoop系统的最新进展(1)

热门文章

  1. JVM 专题十三:运行时数据区(八)直接内存
  2. python爬虫拉钩网:{&#39;msg&#39;: &#39;您操作太频繁,请稍后再访问&#39;, &#39;clientIp&#39;: &#39;113.57.176.181&#39;, &#39;success&#39;: False}
  3. 数据可视化之powerBI技巧(二)Power BI性能分析器,原来还有这个功能
  4. 数据可视化之分析篇(五)如何使用Power BI计算新客户数量?
  5. 计算机网络学习socket--day3
  6. 04 . Filebeat简介原理及配置文件和一些案例
  7. MySQL中的循环
  8. 【Logisim实验】构建立即数-随机存储器-寄存器的传送
  9. SpringBoot实现前后端数据交互、json数据交互、Controller接收参数的几种常用方式
  10. Bootstrap++:bootstrap-select 使用