事件 - DOM编程
何为 DOM 事件,HTML DOM 使JavaScript 有能力对 HTML 事件做出反应。
1. 事件流
一个 DOM 事件可以分为捕获过程、触发过程、冒泡过程。
下面一个<a>元素被点击为例。

- 红虚线:捕获过程。当DOM事件发生时,它会从
window节点一路跑下去直到触发事件元素的父节点为止,去捕获触发事件的元素。 - 红绿实线:触发过程。当事件被捕获之后就开始执行事件绑定的代码。
- 绿虚线:冒泡过程。当事件代码执行完毕后,浏览器会从触发事件元素的父节点开始一直冒泡到
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为设定是否为捕获过程,默认事件均为冒泡过程,只有useCapture为true时才会启用捕获过程。
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>

EventUIEventFocusEventInputEventKeyboardEventMouseEventWheelEvent
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的区别
参考:
事件 - DOM编程的更多相关文章
- 读书笔记:JavaScript DOM 编程艺术(第二版)
读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅. 内容也有自己的一些补充. JavaScript DOM 编程艺术(第二版) 1.JavaScript简史 JavaScript由Nets ...
- 《高性能javascript》 领悟随笔之-------DOM编程篇(二)
<高性能javascript> 领悟随笔之-------DOM编程篇二 序:在javaSctipt中,ECMASCRIPT规定了它的语法,BOM实现了页面与浏览器的交互,而DOM则承载着整 ...
- Dom编程
Dom编程 Dom是一种用于HTML和XML文档的编程接口,是HTML页面的模型,将每个标签都做为一个对象,JavaScript通过调用DOM中的属性.方法就可以对网页中的文本框.层等元素进行编程控制 ...
- JavaScript DOM 编程艺术·setInterval与setTimeout的动画实现解析
先贴上moveElement()函数的大纲,为了方便观看,删了部分代码,完整版粘到文章后面. function moveElement(elementID,final_x,final_y,interv ...
- 高性能JavaScript笔记一(加载和执行、数据访问、DOM编程)
写在前面 好的书,可能你第一遍并不能领会里面的精魂,当再次细细品评的时候,发现领悟的又是一层新的含义 (这段时间,工作上也不会像从前一样做起来毫不费力,开始有了新的挑战,现在的老大让我既佩服又嫉妒,但 ...
- DOM编程(每天有学习一点篇)
每次想到“DOM”编程就会自然联想到“性能瓶颈”.我觉得有两部分原因: 1.DOM自己本身操作代价昂贵,因为浏览器通常要求DOM 实现和JavaScript 实现保持相互独立: 2.嘿嘿,本人自身的原 ...
- web前端基础——初识HTML DOM编程
1 HTML DOM编程概述 文件对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理HTML的标准编程接口.由于HTML文档被浏览器解析后就是一棵DOM树,要改 ...
- JavaScript DOM编程艺术学习笔记(一)
嗯,经过了一周的时间,今天终于将<JavaScript DOM编程艺术(第2版)>这本书看完了,感觉受益匪浅,我和作者及出版社等等都不认识,无意为他们做广告,不过本书确实值得一看,也值得推 ...
- JS之DOM编程
为什么学dom编程? 通过dom编程,我们可以写出各种网页游戏 dom编程也是我们学习ajax技术的基础,所以我们必需掌握好dom编程. dom编程简介 DOM=Document Object Mo ...
随机推荐
- java 面向对象(四十一):反射(五)反射应用二:获取运行时类的完整结构
我们可以通过反射,获取对应的运行时类中所有的属性.方法.构造器.父类.接口.父类的泛型.包.注解.异常等....典型代码: @Test public void test1(){ Class clazz ...
- java IO流 (二) IO流概述
1.流的分类* 1.操作数据单位:字节流.字符流* 2.数据的流向:输入流.输出流* 3.流的角色:节点流.处理流 图示: 2.流的体系结构 说明:红框对应的是IO流中的4个抽象基类.蓝框的流需要大家 ...
- python 面向对象专题(六):元类type、反射、函数与类的区别、特殊的双下方法
目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3. 函数与类的区别 4. 特殊的双下方法 1. 元类type type:获取对象 ...
- 并发编程之synchronized锁(一)
一.设计同步器的意义 多线程编程中,有可能会出现多个线程同时访问同一个共享.可变资源的情况,这个资源我们称之其为临界资源:这种资源可能是:对象.变量.文件等. 共享:资源可以由多个线程同时访问 可变: ...
- bzoj3526[Poi2014]Card*
bzoj3526[Poi2014]Card 题意: 有n张卡片在桌上一字排开,每张卡片上有两个数,第i张卡片上,正面的数为a[i],反面的数为b[i].有m个操作,第i个操作会交换c[i]和d[i]两 ...
- java实现判断时间是否为合法时间
最近遇到一个需求,输入字符串,判断为日期的话再进行后面的比较大小之类的操作,但是合法日期的格式也是比较多的,利用正则表达式又太长了.所以后面利用的方法就是,先把输入的字符串转成一种固定的时间格式,然后 ...
- SpringBoot2.x入门教程:引入jdbc模块与JdbcTemplate简单使用
这是公众号<Throwable文摘>发布的第23篇原创文章,收录于专辑<SpringBoot2.x入门>. 前提 这篇文章是<SpringBoot2.x入门>专辑的 ...
- django admin后台管理功能的学习
1.简要说明 用过Django框架的童鞋肯定都知道,在创建完Django项目后,每个app下,都会有一个urls.py文件,里边会有如下几行: from django.contrib import a ...
- CSS3伪元素 ::first-letter ::first-line ::selection
首先,关于伪元素的语法: 有的时候单冒号也能用,但最好写双冒号. 伪类:匹配的是元素(不同状态或结构的). 伪元素:匹配的是元素中的一部分内容(首字符,首行文本). ::first-letter 匹配 ...
- JavaScript数组在指定某个元素前或后添加元素
//原数组 var s = [['g','g'],['h','h'],['i','i']]; //要添加的元素 var s1 = ['a','b','c']; //要添加的元素 var s2 = [' ...