DOM--事件操作

1. 事件基础

JavaScript可以让我们创建动态页面,而事件是可以被 JavaScript 侦测到的行为。简单理解事件就是: 触发--- 响应机制
网页中的每个元素都可以产生某些可以触发 JavaScript 的事件,例如,用户点击某按钮时产生一个 事件,然后去执行某些操作。

1.1 事件三要素

① 事件源 (谁)
② 事件类型 (什么事件)
③ 事件处理程序 (做啥事)

1.2 案例解析

<body>
    <button>点击</button>
    <script>
        // 事件三要素
        // 1. 获取元素(即为事件源)
        let btn = document.querySelector("button");
        // 2. 绑定事件(这里绑定的是点击事件)
        btn.onclick = function() {
            // 3. 事件处理程序(这里为弹出alert 警示框)
            alert("今天天气真好!")
        };
    </script>
</body>

对此案例进行分析,可知其事件三要素如下:

① 获取事件源(按钮)
② 注册事件(绑定事件),使用 onclick(点击事件)
③ 编写事件处理程序,写一个函数弹出 alert 警示框

1.3 执行事件的步骤

① 获取事件源
② 注册事件(绑定事件)
③ 添加事件处理程序(采取函数赋值形式

1.4 常见的鼠标事件

 1.5 mouseover和mouseenter的区别

<body>
    <div>
        <span>我是鼠标移入over</span>
    </div>
    <div>
        <span>我是鼠标进入enter</span>
    </div>
    <script>
        // 1.获取元素(事件源)
        let divs = document.querySelectorAll('div');
        // 定义变量i,让其在鼠标移入后进行自加
        let i = 0;
        // 2.绑定事件(鼠标移入事件)
        divs[0].onmouseover = function() {
        // 3.事件处理程序
            let spans = document.querySelectorAll('span');
            spans[0].innerHTML = i++;
        };
        // 定义变量j,让其在鼠标进入后进行自加
        let j = 0;
        // 2.绑定事件(鼠标移入事件)
        divs[1].onmouseenter = function() {
        // 3.事件处理程序
            let spans = document.querySelectorAll('span');
            spans[1].innerHTML = j++;
        }
    </script>
</body>

通过该案例可以得知:

onmouseover事件,不仅鼠标经过自身盒子会触发,而且经过子节点的时候也会触发

② 而onmouseenter事件,鼠标只有经过自身盒子才会触发,经过子节点的时候不触发,原因是mouseenter不会冒泡

③ onmouseout和onmouseover是一对,所以同样经过子节点会触发事件,而onmouseleave和onmouseenter是一对,所以其一样不会冒泡。

2. 事件高级

2.1 注册事件(绑定事件)  

给元素添加事件,称为注册事件或者绑定事件。注册事件有两种方式:传统方式和方法监听注册方式

(1)传统注册方式

① 利用 on 开头的事件,如 onclick 
② 使用语法: eventTarget.onclick = function() {} 
③ 特点: 注册事件的唯一性
同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数;

(2)方法监听注册方式

① w3c 标准 推荐方式
addEventListener()一个方法
③ 特点:同一个元素同一个事件可以注册多个监听器,并按注册顺序依次执行

语法:eventTarget.addEventListener(type, listener, [useCapture])

eventTarget.addEventListener()方法将指定的监听器注册到 eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。
该方法接收三个参数:
① type:事件类型字符串,比如 click 、mouseover ,注意这里不要带 on
② listener:事件处理函数,事件发生时,会调用该监听函数
③ useCapture:可选参数,是一个布尔值,默认是 false,false表示处于冒泡阶段,true表示处于捕获阶段。

2.2 删除事件(解绑事件)

(1)传统注册方式

eventTarget.onclick = null;  // 移除目标对象上的点击事件

(2)方法监听注册方式

// 删除绑定事件,事件处理函数有可能被移除,那么在使用方法监听注册时就不要使用匿名函数
eventTarget.removeEventListener('事件类型', 原处理函数); 
比如:
<button>监听绑定事件方式</button>
<script>
let btn = document.querySelector('button');
// 注册事件时给处理函数命名为fun
btn.addEventListener('click', function fun() {
    console.log(8765);
// 删除事件时,直接使用fun即可
    btn.removeEventListener('click', fun)
})

2.3 DOM事件流

 所谓事件流描述的是从页面中接收事件的顺序。而DOM 事件流,指的是事件发生时,在元素节点之间按照特定顺序传播的过程

DOM 事件流分为3个阶段: 
① 捕获阶段
② 当前目标阶段
③ 冒泡阶段 

(1)事件捕获: 网景最早提出,由 DOM 最顶层节点开始,然后逐级向下传播到到最具体元素接收的过程。 即由外向内,依次记录各级元素上绑定的处理函数,只记录,不执行

(2)事件冒泡: IE 最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点的过程。即由内向外依次触发捕获阶段记录的各级父元素上的处理函数

注意:
1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。
2. onclick只能得到冒泡阶段
3. addEventListener(type, listener, [useCapture])第三个参数如果是 true,表示在事件捕获阶段调用事件处理程序;如果是 false(不写默认就是false),表示在事件冒泡阶段调用事件处理
程序。
4. 实际开发中我们很少使用事件捕获,我们更关注事件冒泡。
5. 有些事件是没有冒泡的,比如 onblur、onfocus、onmouseenter、onmouseleave

2.4 事件对象

所谓事件对象就是:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象 event,它有很多属性和方法。

(1)事件对象的使用语法

eventTarget.onclick = function(event) {
 // 这个 event 就是事件对象,我们还喜欢写成 e 或者 ev 
} 
eventTarget.addEventListener('click', function(event) {
 // 这个 event 就是事件对象,我们还喜欢写成 e 或者 ev 
})

这个 event 是个形参,系统帮我们设定为事件对象,不需要传递实参过去。
当我们注册事件时, event 对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)。

 (2)事件对象的兼容性方案 

事件对象本身的获取存在兼容问题:

1. 标准浏览器中是浏览器给方法传递的参数,只需要定义形参 e 就可以获取到。
2. 在 IE6~8 中,浏览器不会给方法传递参数,如果需要的话,需要到 window.event 中获取查找。
解决方案: e = e || window.event;

(3)事件对象的常见属性和方法

e.target 和 this 的区别:
① this 是事件绑定的元素, 这个函数的调用者(绑定这个事件的元素) 
e.target 是事件触发的元素

 2.5 阻止事件冒泡

事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点。
事件冒泡本身的特性,会带来的坏处,也会带来的好处,需要我们灵活掌握。

阻止事件冒泡的标准写法:

// 利用事件对象里面的 stopPropagation()方法
e.stopPropagation() 

2.6 事件委托(代理、委派)

因为浏览器触发事件时采用的是遍历队列的方式,队列中监听的对象多,遍历查找的就慢,事件响应的速度就可能延迟。而利用事件冒泡本身的特性进行事件委托,则可以减少监听对象,从而提升响应速度

事件委托的原理:不是每个子节点单独设置事件监听器,而是把事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点,e.target代替this获得目标元素。

<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
    </ul>
    <script>
        // 事件委托的核心原理:给父节点添加监听器,利用事件冒泡影响每一个子节点
        // 获取父元素ul
        let ul = document.querySelector('ul');
        // 给父元素注册监听事件
        ul.addEventListener('click', function(e) {;
            // e.target 表示我们触发的对象
            // 目标元素必须经过判断,符合条件,才能指向后续操作
            if (e.target.nodeName == 'LI') {
                e.target.style.backgroundColor = 'pink';
            }
        })
    </script>
</body>

点击每个 li 都会将其自身的背景色改为粉色,以前需要给每个 li 注册事件,访问 DOM 的次数越多,这就会延长整个页面的交互就绪时间。

而使用事件委托,则只需要给他们的父元素ul注册一次事件即可,利用冒泡特性实现这一需求,由于只操作了一次 DOM ,所以提高了程序的性能。

因此,当多个平级子元素都要绑定相同的事件时,只要将事件在父元素绑定一次就行,所有的子元素都可通过冒泡原理共享父元素的事件使用 。

2.7 常用的鼠标事件

event对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象 
MouseEvent 和键盘事件对象 KeyboardEvent
。 

2.8 常用的键盘事件

(1)常用键盘事件

事件除了使用鼠标触发,还可以使用键盘触发。

注意: 
1. 如果使用addEventListener 不需要加 on
2. onkeypress 和前面2个的区别是,它不识别功能键,比如左右箭头,shift 等。
3. 三个事件的执行顺序是: keydown -- keypress --- keyup.

(2)键盘事件对象

注意: 
1. onkeydown 和 onkeyup 不区分字母大小写,onkeypress 区分字母大小写。
2. 在我们实际开发中,我们更多的使用keydown和keyup, 它能识别所有的键(包括功能键)
3. keypress 不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值.

(3)ASCII 表

本文主要介绍理论知识,下篇文章则会在此基础上进行项目实操。

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值