JS高级程序设计第十三章.个人学习笔记

本文内容:

  • 理解事件流
  • 使用事件处理程序
  • 不同的事件类型


基本概念:javaScript与HTML之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。可以使用侦听器(或处理程序)来预订事件,以便事件发生时执行相应的代码。这种在传统软件工程中被称为观察员模式的模型,支持页面的行为(JavaScript)与页面的外观(HTML和CSS代码)之间的松散耦合。


1.事件流


事件流分为两种:IE的冒泡流 Nercape Communicator的事件捕获流


1.1 事件冒泡


IE的事件流叫做事件冒泡,即事件开始时有最具体的元素(文档中嵌套层次最深的那个节点)接受,然后逐级向上传播到较为不具体的节点(文档)。

例如:

<!DOCTYPE html>
<html>
<head>
    <title>Event Bubbling Example</title>
</head>
<body>
    <div id='myDiv'>Click Me</div>
</body>
</html>复制代码

如果你单击了页面中的<div>元素,那么这个click事件会按照如下顺序传播:

  1. <div>
  2. <body>
  3. <html>
  4. document

也就是说,click事件首先在<div>元素上发生,而这个元素就是我们单击的元素。然后,click事件沿DOM树向上传播,在每一级节点上都会发生,直至传播到document对象。


1.2 事件捕获

Nercape Communicator踢出的另一种事件流叫做事件捕获。

事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于事件到达预定目标之前捕获它。

如果以之前代码作为例子,那么元素就会以下面的顺序触发click事件

  1. document
  2. <html>
  3. <body>
  4. <div>

在事件捕获的过程中,document对象首先接收到click事件,然后事件沿DOM树依次向下,一直传播到事件的实际目标,即<div>元素。

由于老版本的浏览器不支持,所以很少使用事件捕获,所以只有在特殊需要时再使用事件捕获。


1.3 DOM事件流

“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段

首先发生的是事件捕获,为截获事件提供了机会。

然后是实际的目标接收到事件。

最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。


在DOM事件流中,实际的目标(div元素)在捕获阶段不会接收到事件。这意味着在捕获阶段,事件从document到<html>再到<body>后就停止了。下一个阶段是“处于目标”阶段,于是事件在div上发生,并在事件处理中被看成冒泡阶段的一部分。

多数支持DOM事件流的浏览器都实现了一种特定的行为;即使'DOM2级事件'规范明确要求捕获阶段不会涉及事件目标,但IE9、Safari、Chrome、Firefox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件。结果就是有两个机会在目标对象上操作事件。

IE9、Safari、Chrome、Firefox和Opera9.5都支持DOM时间流;IE8及更早版本不支持DOM事件流


2. 事件处理程序

事件就是用户或浏览器自身执行的某种动作。click、load和mouseover,都是事件的名字。而相应某个事件的函数就叫做事件处理程序(或事件侦听器)。


2.1 HTML事件处理程序

某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的HTML特性来制定。这个特性的值应该是能够执行的JavaScript代码。

例如,要在按钮被单击时执行一些JavaScript,可以像下面这样编写代码:

<input type='button' value='Click Me' onclick='alert("Clicked")'/>复制代码

事件处理程序中的代码在执行时,有权访问全局作用域中的任何代码。

在HTML中定义的事件处理程序可以包含要执行的具体动作,也可以调用在页面其他地方定义的脚本,如下面的例子所示:

<script type='text/javascript'>
    function showMessage(){
        alert('hello world');
    }
</script>
<input type='button' value='Click Me' onclick='showMessage()' />复制代码


在这个例子中,单间牛牛就会调用showMessage()函数。这个函数实在一个独立<script>元素中定义的,当然也可以被包含在一个外部文件中。这样指定时间处理程序具有一些独到之处。首先,这样会创建一个封装着元素属性值的函数。这个函数中有一个局部变量event,也就是事件对象

<input type='button' value='Click Me' onclick='alert(event.type)' />    // click

复制代码

通过event变量,可以直接访问事件对象,你不用自己定义它,也不用从函数的参数列表中读取。在这个函数内部,this值等于事件的目标元素,例如:

<input type='button' value='Click Me' onclick='alert(this.value)' /> //Click Me复制代码

html中指定事件处理程序有两个缺点。

首先,存在一个时差问题,如果某个事件处理程序一加载就触发,而页面还不具备执行条件的话,就会引发错误,因此很多HTML事件处理程序都会被封装在一个try-catch块中,以便错误不会浮出水面。

另一个缺点是,这样扩展事件处理程序的作用于连在不同浏览器中会导致不同结果。不同JavaScript引擎遵循的标识符解析规则略有差异,很可能会在访问非限定对象成员时出错。


因为HTML指定事件处理程序时HTML与JavaScript代码紧密耦合,所以一般我们都选择使用JavaScript指定事件处理程序。


2.2 DOM0级事件处理程序

使用DOM0级方法指定的事件处理程序被认为是元素的方法。因此,这时候的事件处理程序实在元素的作用域中进行;换句话说,程序中的this引用当前元素。

要删除DOM0级事件处理程序的方法也简单:

btn.onclick = null复制代码


2.3 DOM2级事件处理程序

“DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:

addEventListener() 和 removeEventListener()。

所有DOM节点中都包含这两个方法,并且他们都接受3个参数:

要处理的事件名、作为事件处理程序的函数 和 一个布尔值

最后一个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;

如果是false,表示在冒泡阶段调用事件处理程序

使用DOM2级方法添加事件处理程序的主要好处是可以添加多个事件处理程序

通过addEventListener()添加的事件处理程序只能使用removeEventListener()来移除;移除时传入的参数与添加处理程序时使用的参数相同。这也意味着通过addEventListener()添加的匿名函数(也就是第二个参数)将无法移除。

不建议在事件捕获阶段注册事件处理程序


2.4 IE事件处理程序

IE实现了与DOM中类似的两个方法: attachEvent()和detaEvent()。这两个方法接受相同的两个参数:事件处理程序名称与事件处理程序函数。IE8只支持事件冒泡,所以attachEvent添加的事件都会被添加到冒泡阶段。

在IE中使用attachEvent时,this 等于 window。

为同一个元素添加多个事件处理程序时,并非以添加的顺序执行,而是以相反的顺序执行。

attachEvent添加的事件可以通过detachEvent来移除,道理跟DOM方法一样。


3.事件对象

在触发DOM上的某个事件时,会唱生一个事件对象event,这个对象中包含这所有与事件有关的信息。包括导致事件的元素,事件的类型以及其他与特定事件相关的信息。例如,鼠标操作导致的事件对象中,会包含鼠标位置的信息,而键盘操作导致的事件对象中,会包含与按下的键有关的信息。所有浏览器都支持event对象,但支持方式不同。

3.1 DOM中的事件对象

兼容DOM的浏览器会将一个event对象传入到事件处理程序中。无论指定时间处理程序时使用说明方法,都会传入event对象。

event对象包含与创建它特定事件有关的属性和方法。所有事件都会有下面列出的成员。

属性/方法(只读)                           类型                         说明

bubbles                                    Boolean                  表明事件是否冒泡
cancelable                                Boolean                表明事件是否可以取消事件的默认行为
currentTarget                           Element           其事件处理程序当前正在处理事件的那个元素
defaultPrevented                      Boolean                 为true表示已经调用了preventDefault()
detail                                         Integer                      与事件相关的细节信息
eventPhase                                Integer        调用事件处理程序的阶段:1表示捕获,2表示                                                                          处于目标,3表示冒泡阶段
PreventDefault                       Function                     取消时间的默认行为。如果cancelable是true,则可以使用这个方法
stopImmediatePropagation()  Function       调用事件处理程序的阶段:1表示捕获,2表示 处于目标,3表示冒泡阶段
 stopPropagation()                 Function        取消时间的进一步捕获或冒泡。不过bubbles为                                                                         true则可以使用这个方法
target                                     Element          事件的目标
trusted                                    Boolean          为true表示事件是浏览器生成的,为false表示                                                                         事件由开发人员通过js创建的
type                                           String            被触发的事件的类型
view                                        AbstractView     与事件关联的抽象视图。等同于发生事件的                                                                               window对象


在事件处理程序内部,独享this始终等于CurrentTarget的值,而target则只包含事件的实际目标。如果直接将时间处理程序指定给了目标元素,则this、currentTarget和target包含相同的值。

event.target保存的是触发事件的元素
event.currentTarget和this保存的是绑定事件的元素


HTML5事件

hashchange事件

在URL的参数列表发生变化时通知开发人员。

必须要把hashchange事件处理程序添加给window对象,然后URL参数列表只要变化就会调用它。此时的event对象应该额外包含两个属性:oldURL和newURL。这两个属性分别保存着参数列表变化前后的完整URL。



4.9 触摸与手势事件

touchstart: 当手指触摸屏幕时触发;即使已经有一个手指放在了屏幕上也会触发。
touchmove:当手指在屏幕上滑动时连续地触发。在这个事件发生期间,调用preventDefault()可以阻止滚动。
touchend:当手指从屏幕上移开时触发
touchcancel:当系统停止跟踪触摸时触发。

每个触摸事件的event对象都提供了在鼠标事件中常见的属性:bubbles、cancelable、view、clientX、clientY、screenX、screenY、detail、altKey、shiftKey、ctrlKey和metaKey。

除了常见的DOM属性外,触摸事件还包含下列三个用于跟踪触摸的属性。

touches:表示当前跟踪的触摸操作的Touch对象的数组。
targetTouchs: 特定于事件目标的Touch对象的数组。
changeTouches:表示自上次触摸以来发生了什么改变的Touch对象的数组。

每个Touch对象包含下列属性

clientX:触摸目标在视口中的x坐标。
clientY:触摸目标在视口中的y坐标。
identifier:标识触摸的唯一ID。
pageX:触摸目标在页面中的x坐标。
pageY:触摸目标在页面中的y坐标。
screenX:触摸目标在屏幕中的x坐标。
screenY:触摸目标在屏幕中的y坐标。
target:触摸的DOM节点目标。


转载于:https://juejin.im/post/5bd3fb8d6fb9a05d0b147e3f

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值