JavaScript 笔记(13)- 事件

原创 乘风逐月 随笔 JavaScript 303阅读 2018-05-31 16:00:59 举报

一、事件流

JavaScript 与 HTML 之间的交互是通过事件实现的。事件是文档或浏览器窗口中发生的一些特定交互瞬间。可以使用处理程序来预订事件,以便事件发生时执行相应的代码。事件流描述的是从页面中接受事件的顺序。
1.事件冒泡
IE 的事件流叫事件冒泡,即事件开始时由最具体的节点接受,然后逐级向上传播到较为不具体的节点。
2.事件捕获
事件捕获的思想是不太具体的节点更早接受到事件,而最具体的节点最后接受到事件。事件捕获的用意是在事件达到目标元素之前捕获它。
3.DOM事件流
DOM事件流包括三个阶段:事件捕获阶段,处于目标阶段,事件冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会,然后是实际的目标接受到事件,最后是事件冒泡,在这个阶段对事件作出响应。

二、事件处理程序

响应事件的函数就叫事件处理程序(或叫侦听器)。

1.HTML事件处理程序

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

2.JavaScript 指定事件处理程序

(1)使用事件处理程序属性
获取一个元素,将一个函数赋值给该元素的事件处理程序属性,函数中 this 引用当前元素。删除指定的事件程序,只需将事件处理程序属性的值设为 null。

(2)addEventListenter() 和 removeEventListenter()
addEventListenter() 和 removeEventListenter() 方法用于指定和删除事件处理程序,所有 DOM 节点都有这两个方法,并且它们都接受三个参数:要处理的事件名、作为事件处理程序的函数、一个布尔值。最后的参数布尔值如果为 true,表示在捕获阶段调用事件处理程序,为 false 表示在冒泡阶段调用事件处理程序。

注:
a. 这里添加的事件也是依附元素的作用域中运行,this 引用当前元素。可以为元素添加两个事件处理程序,会按照添加的顺序先后触发。
b. 通过 addEventListenter() 添加的事件只能通过 removeEventListenter()来移除,移除时传入的参数与添加处理程序时相同,这意味着通过 addEventListenter() 添加的匿名函数将无法移除。

三、事件对象

在触发 DOM 上的某个事件时,会产生一个事件对象 event,这个对象中包含了所有与事件相关的信,兼容 DOM 的浏览器,会将事件对象 event 传入到事件处理程序中。

事件对象包含的属性方法

event 对象包含与创建它的特定事件有关的属性和方法,触发的事件类型不同,可用的属性和方法也不同。但是所有事件都会有一下属性和方法:

属性/方法类型读/写说明
targetElement只读事件的目标
currentTargetElement只读其事件处理程序当前正在处理的那个元素
bubblesBoolean只读表示事件是否冒泡
cancelableBoolean只读表示是否可以取消事件的默认行为
defaultPreventedBoolean只读为true表示已经调用了 preventDefault()方法
detailInteger只读与事件相关的事件信息
eventPhaseInteger只读调用事件处理程序的阶段:1表示捕获阶段,2表示处于目标阶段,3表示冒泡阶段
preventDefault()Function只读取消事件的默认行为,如果 cancelable 为true,则可以使用这个方法
stopPropagation()Function只读取消事件的进一步捕获或冒泡,如果 bubbles 为true,则可以使用这个方法
trustedBoolean只读为true表示事件是浏览器生成的 ,false则为开发人员通过js创建的
typeString只读被触发的事件的类型

注:
a. 在事件处理程序的内部,对象 this 始终等于 currentTarget 的值,而 target 则只包含事件的实际目标。如果直接将事件处理程序指定给了目标元素,则 this,currentTarget,target 包含相同的值。如果事件处理程序存在于父节点中,这些值不相等。

b. 只有事件处理程序执行期间,event 对象才会存在;一旦事件处理程序执行完毕,event 对象就会被销毁。

四、事件类型

1.UI事件

(1)load:
a. 当页面完全加载后在 window 上触发
b. 当所有框架都加载完毕后在框架集 frames 上触发
c. 当图像加载完毕时在 img 元素上触发
(2)unload:
a. 当页面完全卸载后在 window 上面触发
b. 当所有框架都卸载后在框架集上触发
(3)error:
a. 当发生 JavaScript 错误时在 window 上出触发
b. 当无法加载图像时在 img 元素上触发
(4)select: 当用户选择文本框(input/textarea)中的一个或多个字符时触发
(5)resize: 当窗口或框架的大小改变时在 window 或框架上触发
(6)scroll: 当用户滚动带滚动条的元素时,在该元素上触发

2.焦点事件

(1)blur: 在元素失去焦点时触发,这个事件不会冒泡
(2)focus: 在元素获取焦点时触发,这个事件不会冒泡

3.鼠标事件

(1)click: 单击鼠标左键时触发
(2)dbclick: 双击鼠标左键时触发
(3)mousedown: 按下鼠标任意按钮时触发
(4)mouseenter: 鼠标光标从元素外部移入元素内时触发
(5)mouseleave: 鼠标光标从元素内部移动到元素外时触发
(6)mousemove: 鼠标光标在元素内部移动时重复触发
(7)mouseout: 鼠标光标在元素上方,移入另一个元素时触发,另一个元素可以是兄弟元素或子元素
(8)mouseover: 鼠标光标从元素外部移入元素内时触发
(9)mouseup: 释放鼠标按钮时触发
注: 只有在同一个元素上相继触发 mousedown 和 mouseup 事件,才会触发 click 事件;如果 mousedown 和 mouseup 中的一个被取消,就不会触发 click 事件。

4.事件的位置信息

(1)客户区坐标位置
event.clientX 和 event.clientY 表示事件发生时鼠标指针在视口中的水平和垂直坐标。
(2)页面坐标位置
event.pageX 和 event.pageY 表示事件发生时鼠标指针在页面中的水平和垂直坐标。
在页面没有滚动的情况下,event.clientX 和 event.clientY 的值与 event.pageX 和 event.pageY 的值相等。
(3)屏幕坐标位置
event.screenX 和 event.screenY 表示事件发生时鼠标指针在整个电脑屏幕中的水平和垂直坐标。

5.修改键

键盘上的 Shift、Ctrl、Alt、Meta(在Windows键盘中就是Windows键,在苹果机中就是Cmd键),它们经常被用来修改鼠标事件的行为。DOM 为此规定了4个属性,表示修改键的状态:shiftKey,ctrlKey,altKey 和 metaKey。这些属性的值都是布尔值,相应键被按下则值为true,否则为false。

6.鼠标按钮

当鼠标被按下或释放时,event 对象包含 button 属性,表示被按下或释放的是鼠标按键。DOM 的 button 属性有三个值:0表示鼠标左键,1表示中间的滚轮按钮,2表示鼠标右键

7.鼠标滚轮事件

当用户通过鼠标滚轮与页面交互、在垂直方向上滚动页面时,就会触发 mousewheel 事件,这个事件可以在任何元素上触发,最终都会冒泡到 document 或 window 上。该事件对应的 event 对象上包含一个特殊的属性 wheelDelta ,当用户向前滚动鼠标滚轮时, wheelDelta 是120的倍数,当向后滚动滚轮时 wheelDelta 是-120的倍数。

8.键盘事件

(1)keydown: 按下键盘上任意键时触发,若按住不放则重复触发
(2)keypress: 按下字符键时触发,若按住不放则重复触发
(3)keyup: 是否键盘上的按键时触发
用户按下字符键时,先触发 keydown,然后是 keypress,最后是 keyup。若按下非字符键,先触发 keydown,然后是 keyup 事件。

9.键码

发生 keydown 和 keyup 事件时,event 对象的 keyCode 属性中会包含一个代码,与键盘上的按键对应。
常用keyCode:

键码
退格(Backspace)8
回车(Enter)13
左箭头37
上箭头38
右箭头39
下箭头40
10. textInput 事件

当用户在可编辑区域中输入字符时,就会触发该事件。
(1)textInput 与 keypress 事件的区别:
a. 只有编辑区域才能触发 textInput 事件,而任何可以获取焦点的元素都可以触发 keypress 事件
b. 只有用户按下能够输入实际字符的键才能触发 textInput 事件,而 keypress 事件则在按下那些能够影响文本显示的键时也会触发(如退格键)。
(2)event.data 属性
textInput 的事件对象中有一个 data 属性,该属性的值就是用户输入的字符。

11.contextmenu事件

contextmenu事件用以表示何时应该显示上下文菜单,以便开发人员取消默认的上下文菜单而提供自定义的菜单。
a. contextmenu事件是冒泡的,因此可以为document指定一个事件处理程序。这个事件的目标是用户操作的元素,可以取消这个事件。
b. contextmenu事件是鼠标事件,所有事件对象中包含与光标位置有关的信息。通常使用该事件显示自定义上下文菜单,而使用click事件来隐藏该菜单。

12.beforeunload事件

beforeunload事件会在浏览器页面卸载前触发,该事件是为了可以让开发人员有可能在页面卸载前阻止这一操作。可以通过该事件来取消卸载并继续使用原页面,但是由用户决定是继续留在该页面还是离开页面。
注:这个事件不太靠谱,关闭页面时有时可以触发,有时不能触发。而且提示文字由浏览器决定,不能更改。

3.DOMContentLoaded事件

DOMContentLoaded事件会在形成完整的DOM树之后触发,不会关注图像,css,js等资源是否加载完毕。

4.hashchange事件

hashchange事件会在URL参数列表(即URL中'#'号后面的所有字符串)发生变化时触发,以便于开发人员可以利用URL参数列来保存状态或导航信息。
a. 必须要再window上添加该事件处理程序。
b. 该事件对象有两个特殊的属性:oldURL和newURL,分别保存着参数列表前后变化的完整URL

五、内存和性能

添加到页面上的事件处理程序数量会直接影响页面的整体运行性能,因为函数越多内存占用的越多,性能越差。

1.事件委托

对于‘事件处理程序过多’的问题解决方案就是事件委托。事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

2.移除事件处理程序

每当将事件处理程序指定给元素时,运行中的浏览器代码与支持页面交互的JavaScript代码之间就会建立一个连接。这种连接越多,页面执行起来就越慢。内存中过时不用的‘空事件处理程序’,也是造成web应用程序内存与性能问题的主要原因。事件委托可以限制连接数量,在不需要的时候移除事件处理程序,也可以解决这种问题。
当通过removeChild或replaceChild或innerHTML直接删除了元素,那么原来添加到元素中的事件处理程序极有可能无法被当做垃圾回收。所以移除元素前,先移除事件处理程序。

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复