0


【学习笔记】JS之事件(上)

前言

本篇文章是我的读书笔记,这里我直接从事件开始的原因是我之前没有写博客,最近一段时间才开始。之前的JS笔记也都有写,如果有人想看,欢迎留言/私信,我会把之前的整理出来。


文章目录

JS 与 HTML 的交互是通过事件实现的

事件流

事件流就是描述接收事件的顺序。

IE支持事件的冒泡流,

Netscape Communicator

支持事件的捕获流。

别以为IE要停了就可以不学冒泡流了,DOM事件流是两者的结合哦!

1.事件冒泡

事件会从开始触发的元素逐层向上传播,现代的浏览器中的事件会一直冒泡到

window

对象

在这里插入图片描述

2.事件捕获

事件会从最不具体的节点元素传播到最具体的节点元素,所有浏览器都是从

window

对象开始捕获的,而

DOM2Events

规定是从

document

开始的。通常建议使用事件冒泡

在这里插入图片描述

3.DOM事件流

分为三个阶段:事件捕获、到达目标和事件冒泡。

事件捕获最先发生,为提前拦截事件提供可能。然后,实际的目标元素接收到事件。最后一个阶段是冒泡,最迟要在这个阶段响应事件。

在这里插入图片描述

实际的目标在捕获阶段不会接收到事件,因为在捕获阶段从

document

到html 再到body就结束了。下一阶段再div元素上发生触发事件 “到达目标" 阶段,通常事件处理时被认为是冒泡阶段的一部分。

现代浏览器都会在捕获阶段在事件目标上触发事件,所以会有两个机会处理事件。

事件处理程序

事件意味着用户或浏览器执行的某种动作。为响应事件而调用的函数被称为事件处理程序,通常函数名以

"on"

开头

1.HTML事件处理程序

提前说明:这种方法使用的不多

特定元素支持的每个事件都可以使用事件处理程序的名字以

HTML

属性的形式来指定。因为属性的值是

JS

代码,所以要注意转义问题。

//具体格式如下<input type="button" value="Click Me" onclick="console.log('Clicked')"/>

在该事件处理程序中可以调用在页面其他地方定义的脚本,可以访问全局作用域的一切。

以这种方式指定的事件处理程序,会创建一个函数来封装属性的值,函数有如下性质:

  • 这个函数有一个特殊的局部变量event,其保存的是event对象。函数的this值相当于事件的目标元素。
  • 其作用域链被扩展了。document和元素自身的成员都可以被当成局部变量访问,这是通过this实现的function(){with(document){with(this){//属性值}}}//所以事件处理程序可以直接通过属性名访问自己的属性值。

但这种指定事件处理程序有一些问题:

  1. 时机问题。事件处理程序可能会在元素和用户已经交互后才会运行到,即事件处理程序写在了元素的后面。这时就会报错,所以用此方法注意js代码的位置,可以用try/catch封装
  2. 事件处理程序的作用域链的扩展在不同的浏览器中会有不同的结果。因为不同的js引擎中标识符解析规则存在差异。
  3. HTMLJS有强耦合,修改代码比较麻烦

2.DOM0事件处理程序

这种方法使用的更多

这种方法是传统方法,即把一个函数赋值给一个事件处理程序属性,要使用

js

指定事件处理程序,必须先取得要操作对象的引用

let btn = document.getElementById("myBtn");

然后把这个属性赋值为一个函数即可

//每个元素都有通常小写的事件处理程序属性
btn.onclick=function(){
    console.log("Clicked");};

注:上面的代码在运行之后才会给事件处理程序赋值,如果在页面中上面的代码出现在按钮之后,可能出现没有反应的情况

事件处理程序会在元素的作用域中运行,即

this

等于元素。可以使用

this

引用元素本身和访问元素的任何属性和方法

以这种方式添加事件处理程序是注册在事件流的冒泡阶段。通过将事件处理程序属性的值设置为

null

,可以移除通过

DOM0

方式添加的事件处理程序

3.DOM2事件处理程序

DOM2Events

为事件处理程序的赋值和移除定义了两个方法:

addEventListener()

removeEventListener()

这两个方法的参数一致:事件名、事件处理函数和一个布尔值。

true

表示在捕获阶段调用事件处理程序,

false

(默认)表示在冒泡阶段调用。所有

DOM

节点都有这两种方法。

//用法let btn = document.getElementById("myBtn");lethandler=function(){
    console.log(this.id);}
btn.addEventListener("click", handler,false);
btn.removeEventListener("click", handler,false);

使用此方式的优势可以为一个事件添加多个事件处理程序,

DOM0

只能添加一个。

注:使用这两种方法时不建议添加匿名函数,因为移除事件处理程序时必须保证和添加时的参数值是一样的,匿名函数没有名字所以无法保证相同,就无法移除。

大多情况都会选择将事件处理程序添加到事件流的冒泡阶段,主要原因是跨浏览器兼容性好。放到捕获阶段通常用于拦截事件。

4.跨浏览器事件处理程序

由于

IE

不久就会停用,所以可以不考虑兼容

IE

代码如下:

var EventUtil ={addHandler:function(element, type, handler){if(element.addEventListener)
            element.addEventListener(type, handler,false);else
            element["on"+ type]= handler;}removeHandler:function(element, type, handler){if(element.addEventListener)
            element.removeEventListener(type, handler,false);else
            element["on"+ type]=null;}};

事件对象

DOM

中发生事件时,所有相关信息都会被收集并存储在一个名为

event

的对象中。同样不看

IE

,所以下面说的都是

DOM

事件对象。

event

对象在事件处理程序执行完毕后,就会被销毁。

DOM事件对象

event

对象是传给事件处理程序的唯一参数,不管是

DOM0

还是

DOM2

都会传入这个对象。通过

HTML

属性指定的事件处理程序,同样可以使用。

不同事件生成的事件对象会包含不同的属性和方法,但也有一些公共的属性和方法。如下:

在这里插入图片描述

在这里插入图片描述

this、currentTarget 和 target的区别

在事件处理程序内,

this

对象始终等于

currentTarget

target

只包含事件的实际目标。如果事件处理程序直接添加到实际的目标(比如,将点击事件处理程序直接添加到一个按钮上)这时这三个值都一样的。

如果没有添加到按钮上,而是添加到其父级节点上,那么

target

就和其他两个不一样了。

target

属性等于按钮,但按钮没有注册事件处理程序,所以事件会冒泡到其父级节点上。

this

currentTarget

都等于父级节点。

type属性

type

属性在处理程序处理多个事件时很有用,比如:

let btn = document.getElementById("mybtn");lethandler=function(event){switch(event.type){case"click"://点击事件
            console.log("Clicked");break;case"mouseover"://鼠标在其上方事件
            event.target.style.backgroundColor ="red";break;case"mouseout"://鼠标移走事件
            event.target.style.backgroundColor ="";break;}};
btn.onclick = handler;
btn.onmouseover = handler;
btn.onmouseout = handler;

preventDefault()方法

用于阻止特定事件的默认动作。任何可以使用此方法取消默认行为的事件,其事件对象

cancelable

属性都会设置为

true
let link = document.getElementById("mylink");
link.onclick=function(event){
    event.preventDefalult();};

stopPropagation()方法

用于立即阻止事件流在DOM结构中传播,取消后续的事件捕获或冒泡。

let link = document.getElementById("mylink");
link.onclick=function(event){
    console.log("Clicked");
    event.stopPropagation();};
document.body.onclick=function(event){
    console.log("body clicked");};//Clicked//不会输出body clicked,因为取消了冒泡

eventPhase属性

用于确定事件流当前所处的阶段。

  • 捕获阶段:1
  • 目标上:2
  • 冒泡阶段:3

结语

事件的内容有点多,先讲到这里,后面是关于事件的类型、事件的委托和模拟事件,我们下次再说~~~


阅读的文章是《JavaScript高级程序设计(第四版)》

标签: javascript 前端 css3

本文转载自: https://blog.csdn.net/qq_52546377/article/details/122077846
版权归原作者 聆听逝去的流 所有, 如有侵权,请联系我们删除。

“【学习笔记】JS之事件(上)”的评论:

还没有评论