学习笔记JS之事件(上)
Posted 聆听逝去的流
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习笔记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) //属性值 //所以事件处理程序可以直接通过属性名访问自己的属性值。
但这种指定事件处理程序有一些问题:
- 时机问题。事件处理程序可能会在元素和用户已经交互后才会运行到,即事件处理程序写在了元素的后面。这时就会报错,所以用此方法注意
js
代码的位置,可以用try/catch
封装 - 事件处理程序的作用域链的扩展在不同的浏览器中会有不同的结果。因为不同的
js
引擎中标识符解析规则存在差异。 HTML
和JS
有强耦合,修改代码比较麻烦
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");
let handler = 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");
let handler = 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高级程序设计(第四版)》
以上是关于学习笔记JS之事件(上)的主要内容,如果未能解决你的问题,请参考以下文章