JavaScript学习笔记(十五) 事件模型 上

简介: JavaScript学习笔记(十五) 事件模型

目录


0、DOM 标准

1、事件模型

2、事件处理程序

3、事件类型

4、事件对象


正文


0、DOM 标准


在开始学习 JavaScript 事件模型前,我们首先来了解一下什么是 DOM(Document Object Model)


简单来说,DOM 是 W3C 定义的访问 HTML 和 XML 文档的标准


按照不同的发展阶段,分为不同的级别,分别是 DOM0、DOM1、DOM2、DOM3


DOM0、DOM2、DOM3 都有定义与事件相关的内容,但是 DOM1 没有定义与事件相关的内容


1、事件模型


(1)事件捕获

事件从文档对象上开始,然后往下传递,直到目标对象(从父到子),低版本浏览器不支持事件捕获


d29aa81dc802b306ede27ffc38123bf2_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dzbXJ6eA==,size_16,color_FFFFFF,t_70#pic_center.png

<!DOCTYPE html>
<html>
<head>
    <title>事件捕获</title>
</head>
<body>
    <ul>
        <li>Apple</li>
        <li>Banana</li>
        <li>Cherry</li>
    </ul>
</body>
<script>
    let html = document.documentElement
    html.addEventListener('click', () => { console.log('html') }, true)
    let body = document.body
    body.addEventListener('click', () => { console.log('body') }, true)
    let uls = document.getElementsByTagName('ul')
    for (let ul of uls) { ul.addEventListener('click', () => { console.log('ul') }, true) }
    let lis = document.getElementsByTagName('li')
    for (let li of lis) { li.addEventListener('click', () => { console.log('li') }, true) }
    // 点击列表项,打印结果为:html body ul li
</script>
</html>


(2)事件冒泡

事件从目标对象上开始,然后往上传递,直到文档对象(从子到父),所有的浏览器都支持事件冒泡

4f094ba665535726af7ee45f41543b13_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dzbXJ6eA==,size_16,color_FFFFFF,t_70#pic_center.png



<!DOCTYPE html>
<html>
<head>
    <title>事件冒泡</title>
</head>
<body>
    <ul>
        <li>Apple</li>
        <li>Banana</li>
        <li>Cherry</li>
    </ul>
</body>
<script>
    let html = document.documentElement
    html.addEventListener('click', () => { console.log('html') }, false)
    let body = document.body
    body.addEventListener('click', () => { console.log('body') }, false)
    let uls = document.getElementsByTagName('ul')
    for (let ul of uls) { ul.addEventListener('click', () => { console.log('ul') }, false) }
    let lis = document.getElementsByTagName('li')
    for (let li of lis) { li.addEventListener('click', () => { console.log('li') }, false) }
    // 点击列表项,打印结果为:li ul body html
</script>
</html>


(3)事件流模型

DOM2 定义了事件流模型,这是目前广泛使用的 JavaScript 事件模型,规定事件传递先捕获后冒泡

8893021bad160759e8a1a86cd1fca2f6_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dzbXJ6eA==,size_16,color_FFFFFF,t_70#pic_center.png


<!DOCTYPE html>
<html>
<head>
    <title>事件流模型</title>
</head>
<body>
    <ul>
        <li>Apple</li>
        <li>Banana</li>
        <li>Cherry</li>
    </ul>
</body>
<script>
    let html = document.documentElement
    html.addEventListener('click', () => { console.log('Chtml') }, true)
    html.addEventListener('click', () => { console.log('Bhtml') }, false)
    let body = document.body
    body.addEventListener('click', () => { console.log('Cbody') }, true)
    body.addEventListener('click', () => { console.log('Bbody') }, false)
    let uls = document.getElementsByTagName('ul')
    for (let ul of uls) { ul.addEventListener('click', () => { console.log('Cul') }, true) }
    for (let ul of uls) { ul.addEventListener('click', () => { console.log('Bul') }, false) }
    let lis = document.getElementsByTagName('li')
    for (let li of lis) { li.addEventListener('click', () => { console.log('Cli') }, true) }
    for (let li of lis) { li.addEventListener('click', () => { console.log('Bli') }, false) }
    // 点击列表项,打印结果为:Chtml Cbody Cul Cli Bli Bul Bbody Bhtml
</script>
</html>


2、事件处理程序


(1)DOM0 事件处理程序

通过事件监听函数指定事件处理程序,事件处理程序在冒泡阶段执行

<button id="submit">提交</button>


<script>
    var button = document.getElementById('submit')
    // 对于 DOM0 事件处理函数,this 指向目标对象,这里 this 指向 button
    var handleEvent = function(e) { console.log(this) }
    // 添加事件处理函数 button.onclick = handleEvent
    // 删除事件处理函数 button.onclick = null
    button.onclick = handleEvent
</script>

DOM0 事件处理程序,同一个事件只能绑定一个事件处理函数,后面绑定的处理函数会覆盖前面绑定的处理函数

<button id="submit">提交</button>


<script>
    var button = document.getElementById('submit')
    var sayHello = function(e) { console.log('Hello') }
    var sayGoodbye = function(e) { console.log('Goodbye') }
    button.onclick = sayHello
    button.onclick = sayGoodbye
    // 只会打印 Goodbye
</script>


(2)DOM2 事件处理程序

通过 addEventListener() 添加事件处理程序,通过 removeEventListener() 删除事件处理程序

它们都接收三个参数,分别是事件名称、事件处理函数以及一个布尔类型的值,这个布尔值默认为


如果布尔值为 false,则在冒泡阶段执行处理函数,如果布尔值为 true,则在捕获阶段执行处理函数

<button id="submit">提交</button>


<script>
    var button = document.getElementById('submit')
    // 对于 DOM2 事件处理函数,this 指向目标对象,这里 this 指向 button
    var handleEvent = function(e) { console.log(this) }
    // 添加事件处理函数 button.addEventListener('click', handleEvent)
    // 删除事件处理函数 button.removeEventListener('click', handleEvent)
    button.addEventListener('click', handleEvent)
</script>


DOM2 事件处理程序,同一个事件可以绑定多个事件处理函数,先绑定先执行

<button id="submit">提交</button>


<script>
    var button = document.getElementById('submit')
    var sayHello = function(e) { console.log('Hello') }
    var sayGoodbye = function(e) { console.log('Goodbye') }
    button.addEventListener('click', sayHello)
    button.addEventListener('click', sayGoodbye)
    // 先打印 Hello,再打印 Goodbye
</script>


(3)低版本 IE 事件处理程序(IE9 之前)

通过 attachEvent() 添加事件处理程序,通过 detachEvent() 删除事件处理程序


它们都接收两个参数,分别是事件监听函数名称以及事件处理函数,将在冒泡阶段执行处理函数

<button id="submit">提交</button>


<script>
    var button = document.getElementById('submit')
    // 对于低版本 IE 事件处理函数,this 指向全局对象,这里 this 指向 window
    var handleEvent = function() { console.log(this) }
    // 添加事件处理函数 button.attachEvent('onclick', handleEvent)
    // 删除事件处理函数 button.detachEvent('onclick', handleEvent)
    button.attachEvent('onclick', handleEvent)
</script>


低版本 IE 事件处理程序,同一个事件可以绑定多个事件处理函数,先绑定后执行

<button id="submit">提交</button>


<script>
    var button = document.getElementById('submit')
    var sayHello = function() { console.log('Hello') }
    var sayGoodbye = function() { console.log('Goodbye') }
    button.attachEvent('onclick', sayHello)
    button.attachEvent('onclick', sayGoodbye)
    // 先打印 Goodbye,再打印 Hello
</script>


目录
相关文章
|
28天前
|
JavaScript
js两种移除事件的方法
js两种移除事件的方法
30 2
|
16天前
|
存储 JavaScript 前端开发
js事件队列
【10月更文挑战第15天】
38 6
|
22天前
|
Web App开发 JavaScript 前端开发
深入理解Node.js事件循环和异步编程模型
【10月更文挑战第9天】在JavaScript和Node.js中,事件循环和异步编程是实现高性能并发处理的基石。本文通过浅显易懂的语言和实际代码示例,带你一探究竟,了解事件循环的工作原理及其对Node.js异步编程的影响。从基础概念到实际应用,我们将一步步解锁Node.js背后的魔法,让你的后端开发技能更上一层楼!
|
18天前
|
JavaScript API
深入解析JS中的visibilitychange事件:监听浏览器标签间切换的利器
深入解析JS中的visibilitychange事件:监听浏览器标签间切换的利器
45 0
|
27天前
|
JavaScript
js两种移除事件的方法
js两种移除事件的方法
48 0
|
29天前
|
JavaScript 前端开发
【干货分享】JavaScript学习笔记分享
【干货分享】JavaScript学习笔记分享
52 0
|
1月前
|
JavaScript
js两种移除事件的方法
js两种移除事件的方法
|
1月前
|
JavaScript 前端开发 Android开发
JavaScript触摸touch事件
JavaScript触摸touch事件
|
6月前
|
JavaScript 前端开发
js开发:请解释事件冒泡和事件捕获。
JavaScript中的事件处理有冒泡和捕获两种方式。事件冒泡是从子元素向上级元素传递,而事件捕获则从外层元素向内层传递。`addEventListener`的第三个参数可设定事件模式,`false`或不设为冒泡,`true`为捕获。示例代码展示了如何设置。
48 2
|
4月前
|
JavaScript
js 事件流、事件冒泡、事件捕获、阻止事件的传播
js 事件流、事件冒泡、事件捕获、阻止事件的传播
70 1