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

news/2024/7/8 3:21:07 标签: JavaScript, 事件

0、DOM 标准

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

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

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

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

1、事件模型

(1)事件捕获

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

在这里插入图片描述

<!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)事件冒泡

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

在这里插入图片描述

<!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 事件模型,规定事件传递先捕获后冒泡

在这里插入图片描述

<!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

如果布尔值为 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>

3、事件类型

HTML 与 JavaScript 通过事件进行交互,常见的事件如下:

(1)鼠标事件

  • mousedown:在按下鼠标按键时触发
  • mouseup:在松开鼠标按键时触发
  • click:在点击鼠标时触发
  • dblclick:在双击鼠标时触发
  • mouseenter:在鼠标移入特定范围时触发
  • mouseleave:在鼠标移出特定范围时触发
  • mousemove:鼠标在特定范围内移动时触发
  • mouseover:鼠标移到某元素上触发
  • mouseout:鼠标从某元素移开触发

(2)键盘事件

  • keydown:在按下键盘按键时触发
  • keyup:在松开键盘按键时触发
  • keypress:在按住键盘按键时触发

(3)UI 事件

  • load:在文档或图像加载完成后触发
  • unload:在文档或图像销毁完成后触发
  • error:加载文档或图像时发生错误
  • abort:加载文档或图像时出现中断
  • scroll:在滚动滚动条时触发
  • resize:调整窗口大小时触发

(4)焦点事件

  • focus:在元素获得焦点时触发,事件不冒泡
  • blur:在元素失去焦点时触发,事件不冒泡

(5)表单事件

  • select:在被选定时触发
  • change:在被修改时触发
  • submit:在被提交时触发

4、事件对象

当一个事件被触发时,会产生一个事件对象,这个事件对象会隐式传入事件处理函数

因此,我们可以在事件处理函数中通过事件对象的属性和方法获取事件的相关信息

(1)事件对象的常用属性

  • type事件名称
  • target:触发事件的目标元素
  • currentTarget:触发事件的当前元素
  • bubbles事件是否为冒泡类型
  • cancelBubble:是否取消冒泡行为
  • cancelable:是否能调用 preventDefault() 方法取消默认行为
  • defaultPrevented:是否有调用 preventDefault() 方法
  • eventPhase事件传播的阶段
  • timeStamp:触发事件的时间
  • clientX:鼠标指针相对于浏览器页面的水平坐标
  • clientY:鼠标指针相对于浏览器页面的垂直坐标
  • screenX:鼠标指针相对于屏幕的水平坐标
  • screenY:鼠标指针相对于屏幕的垂直坐标
  • shiftKey:“SHIFT” 键是否被按下
  • ctrlKey:“CTRL” 键是否被按下
  • altKey:“ALT” 键是否被按下
  • metaKey:“meta” 键是否被按下

(2)事件对象的常用方法

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

http://www.niftyadmin.cn/n/1849605.html

相关文章

Android 一个程序A启动程序B

2019独角兽企业重金招聘Python工程师标准>>> 1.首先&#xff0c;要获得程序B的包名 2.Intent intentgetPackageManager.getLaunchIntentForPackage(packageName); startActivity(intent); android获取程序包名&#xff1a;getPackageManager.getInstalledPackage…

如何求地球上两点之间的最短距离_蔡司三坐标Calypso平行平面之间距离的测量方法...

求平行平面之间的距离&#xff0c;这个命题的概念是模糊不清的。例如&#xff1a;1. 求平面1的中心到平面2的垂线&#xff1f;在Calypso内可以使用垂直线或者笛卡尔距离/直角坐标距离实现。但考虑实际两平面不可能理论平行&#xff0c;平面1的各顶点到平面2的垂直距离是不同的&…

马斯诺的行为科学体系的基础

马斯诺的行为科学体系的基础之一是把人的需求分成五个方面&#xff1a;一、生存需要&#xff1b;二、安全需要&#xff1b;三、从属和爱的需要&#xff1b;四、自尊的需要&#xff1b;五、自我实现的需要。东方人与其不完全一样&#xff0c;东方人的需求可分为&#xff1a;富余…

c# 用BitArray来管理包含关系

BitArray是.net自带的引用类型&#xff0c;在名称空间Systems.Collections下面。输入BitArray可以看到它的摘要&#xff1a;“管理位值的压缩数组&#xff0c;该值表示为布尔值&#xff0c;其中 true 表示位是打开的 (1)&#xff0c;false 表示位是关闭的 (0)”。 定义一个BitA…

loss下降auc下降_随机梯度下降法介绍及其参数讲解

算法介绍简单来说&#xff0c;梯度下降就是从山顶找一条最短的路走到山脚最低的地方。但是因为选择方向的原因&#xff0c;我们找到的的最低点可能不是真正的最低点。如图所示&#xff0c;黑线标注的路线所指的方向并不是真正的地方。既然是选择一个方向下山&#xff0c;那么这…

JavaScript学习笔记(十六) XMLHttpRequest

1、介绍 &#xff08;1&#xff09;AJAX&#xff08;Asynchronous JavaScript and XML&#xff09; AJAX 原来是指通过异步 JavaScript 从服务器 XML 文档获取数据&#xff0c;然后更新部分网页&#xff0c;避免刷新整个网页 后来&#xff0c;这个词语慢慢成为在浏览器通过脚…

目前在看的书Visual c++ Net 技术内幕第六版

这本书&#xff0c;讲ATL不错。书上以VC2003.net 为环境讲的。

打包自己的的Class文件为Jar文件

java cvf my.jar *.* (不加-)&#xff0c;则把当前的目录里的所有子目录以及文件打包为my.jar&#xff0c;该jar包就在当前目录下 要想用该jar包需要在classpath下现加.;再加上所在jar包的绝对路径\my.jar。 jar -cf my.jar com则把com下的所有文件打包到jar包。 jar -tvf my.j…