JavaScript学习笔记(12)
来源:互联网 发布:js offsettop 不准确 编辑:程序博客网 时间:2024/06/10 21:15
事件
JS与HTML之间通过事件进行交互。之前的jQuery笔记总结过事件的相关内容,很多重复的东西就省略掉了。事件相关的API很冗杂,很多东西可以即用现查,但基本的核心和概念还是需要掌握的。
1 事件流
事件流其实就是用于描述从页面接收事件的顺序。IE提出了从具体到宽泛的事件冒泡,网景提出了从宽泛到具体的事件捕获。DOM则集成了两家的特点,将事件流划分成三个阶段:
- 事件捕获阶段,为截获事件提供机会
- 处于目标阶段,实际的目标接收到事件
- 事件冒泡阶段,对事件作出响应
2 事件处理程序
事件是用户或浏览器自身执行的某种动作(例如,单击:click,加载:load)。
事件处理程序是响应具体事件的函数(例如,单击处理事件:onclick)。
2.1 HTML事件处理程序
所谓HTML事件处理程序,即在HTML当中直接插入事件监听器。
<input type="button" value="Click" onclick="alert('clicked');">
由于HTML事件处理程序,行为和样式耦合紧密,不利于阅读和修改,所以不应当使用这种方法。
2.2 JavaScript事件处理程序
2.2.1 DOM0级事件处理程序
将一个函数赋值给一个事件处理程序,因为其操作简单可以跨浏览器而一直沿用至今,要使用JS事件处理程序需要先取得要操作对象的引用。
var btn = doucment.getElementById("mybtn");btn.onclick = function(){ alert("this.id");};btn.onclick = null;
DOM0级事件处理程序只有被执行之后,才会和被监听的元素绑定。
DOM0级事件处理程序是属于被监听元素的方法,其中的this就是被监听元素的引用。
将事件处理程序赋值为null,即可删除该方法。
2.2.2 DOM2级事件处理程序
DOM2添加了用于绑定和删除事件处理程序的操作:
- addEventListener(eventName,eventFunction,boolean)
- removeEventListener(eventName,eventFunction,boolean)
布尔值为true,表示在捕获阶段调用事件处理程序
布尔值为false,表示在冒泡阶段调用事件处理程序
var btn = document.getElementById("myBtn");var handler = function(){ alert(this.id);};btn.addEventListener("click",handler,false);btn.removeEventListener("click",handler,false);
为同一元素绑定多个事件处理程序,则它们会按照顺序触发。
removeEventListener()的参数要和addEventListener()的参数一致才可以删除。
通常情况下,都是讲事件处理程序添加到冒泡阶段,以最大限度地兼容各类浏览器。
2.2.3 IE事件处理程序
IE的事件处理与其他浏览器不同,IE实现了类似的方法:
- attachEvent(eventName,eventFunction)
- detachEvent(eventName,eventFunction)
var btn = document.getElementById("myBtn");btn.attachEvent("onclick",function(){ alert("something")});
IE的事件处理程序中this指向全局(window),而不是DOM中的被监听元素。
IE下,一个元素绑定了多个事件处理程序,会逆序执行,后定义的先执行。
移除方法的时候参数也要和添加的时候一样。
2.3 跨浏览器实现事件处理程序
通常使用JavaScript库可以实现这一目的,不过如果需要自己实现细节内容,则需要考虑浏览器的能力检测。
var EventUtil = { addHandler : function(ele,type,handler) { if(ele.addEventListener){ //DOM2级 ele.addEvebtListener(type,handler,false); } else if(ele.attachEvent){ //IE ele.attachEvent("on"+type,handler); } else { //DOM0级 ele["on"+type] = handler; } }, removeHandler : function(ele,type,handler) { if(ele.removeEventListener){ //DOM2级 ele.removeEvebtListener(type,handler,false); } else if(ele.detachEvent){ //IE ele.detachEvent("on"+type,handler); } else { //DOM0级 ele["on"+type] = null; } }};
3 事件对象
3.1 DOM中的事件对象
在触发DOM上的某个时间的时候会产生一个事件对象event,包含了所有与事件有关的信息(导致事件的元素,事件的类型,其他与特定事件相关的信息)。
event对象包含的属性和方法因事件类型不同而存在差异,公有的属性和方法如下(都是只读的):
3.2 IE中的事件对象
IE的event对象在不同的事件处理方法中有所区别。
不同事件触发的event公有的属性如下:
3.3 跨浏览器实现事件对象
继续2.3的例子,继续扩充兼容的实现方法:
var EventUtil = { getEvent : function(event){ return event ? event : window.event; //window.event是IE的方法 }, getTarget : function(event){ return event.target||event.srcElement; //短路运算符 }, prevantDefault : function(event){ if(event.prevantDefault){ event.prevantDefault(); } else { event.returnValue = false; } }, stopPropagation : function(event){ if(event.stopPropagation){ event.stopPropagation(); } else { event.cancelBubble = true; } }};
4 事件类型
DOM3规定了以下几类事件:
- UI事件,用户与页面上的元素交互时触发
- 焦点事件,当元素获得或失去焦点时触发
- 鼠标事件,当用户通过鼠标在页面上执行操作时触发
- 滚轮事件,当使用鼠标滚轮时触发
- 文本事件,当在文档中输入文本时触发
- 键盘事件,当用户通过键盘在页面上执行操作时触发
- 合成事件,当为输入法编辑器输入字符时触发
- 变动事件,当底层的DOM结构发生变化时触发
4.1 UI事件
当所有框架都加载后在框架集上触发
当图像加载后在
<img>
元素上触发当嵌入的内容完全加载后在
<object>
元素上触发 unload 与load相反,当卸载完成之后触发 abort 当用户停止下载过程时,如果没有加载完,则在<object>
元素上触发 error 当JS错误或加载失败的情况下触发 select 当用户选择文本框中的字符时触发 resize 当窗口或框架的大小发生变化时触发 scroll 当滚动带有滚动条的元素是在该元素上触发,<body>
元素中包含所加载页面的滚动条4.2 焦点事件
4.3 鼠标&滚轮事件
4.3.1 定位鼠标
4.4 键盘&文本事件
包含属性data用于显示输入的文本,
inputMethod属性用于表示文本输入的方式(键盘、粘贴、拖放、表单选择、语音、手写)
4.5 复合事件&变动事件
复合事件,IME(输入法编辑器)输入的序列,类似于软键盘等物理键盘上找不到的字符,在输入的时候会触发这一类事件。 compositionstart
,compositionupdate
,compositionend
分别对应了打开IME、输入字符、关闭IME的过程。和文本事件比较类似。
变动事件在DOM结构发生改变时会触发。
4.7 触摸&手势事件
移动端的设备由于其硬件的特殊性,人机交互与PC端也有所不同。
每个触摸事件的event对象都提供了在鼠标事件中常见的属性(定位属性,按键属性等),除此之外,还有几个特有的用于跟踪触摸的属性:
- touches:表示当前跟踪的触摸操作的Touch对象数组
- targetTouches:特定于事件目标的Touch对象数组
- changeTouches:表示自上次触摸以来发生了什么改变的Touch对象的数组。
Touch对象包含标识ID(identitier)、定位属性(clientX/Y,pageX/Y,screenX/Y)、DOM节点目标(target)
手势事件包含了触摸事件的属性并额外有表示手指变化引起的旋转角度的rotation属性和表示两指距离的scale属性。
5 模拟事件
JS可以模拟事件的触发,极大的方便了开发和测试。
5.1 DOM中的事件模拟
在document对象上使用createEvent()
可以创建event对象,该方法的参数时要创建的事件类型的字符串,对应的init方法用于初始化事件,dispatchEvent()
可以触发事件。
//模拟鼠标事件var btn = document.getElementById("mybtn");var event = document.createEvent("MouseEvents");event.initMouseEvent("click",true,true,document.defaultView,0,0,0,0,0,false,false,false,false,0,null);btn.dispatchEvent(event);
5.2 IE中的事件模拟
与DOM的思路类似,document.createEventObject()
(不带任何参数)创建事件对象,返回一个通用的event,手工对event添加必要信息,fireEvent()
触发事件。
6 内存和性能
为了提高页面运行的性能,可以采取一些降低内存占用的手段。
6.1 事件委托
事件委托可以解决事件处理程序过多的问题,将所有的click事件整合到一个事件处理程序去处理,可以避免为每一个可单击元素分别添加事件处理程序。这种方法需要将事件处理程序放在尽量高的层次,以便接到所有的事件冒泡。
最简单的一种实践是用switch分类处理不同类型的单击。
6.2 删除事件处理程序
还有一种解决办法就是及时将无用的事件处理程序删除,在移除元素或节点之前,最好也手工将绑定在其上的事件处理程序删掉。
最简单的删除方法就是将事件处理程序置为null。
- JavaScript学习笔记(12)
- JavaScript学习笔记(三)---JavaScript对象
- javascript学习笔记(一)--初识javascript
- JavaScript 学习笔记(一)
- JavaScript 学习笔记(二)
- JavaScript学习笔记(一)
- JavaScript 学习笔记(一)
- JavaScript 学习笔记(一)
- javascript 学习笔记(1)
- javascript 学习笔记(2)
- javascript 学习笔记(3)
- javascript 学习笔记(4)
- javascript 学习笔记(6)
- JavaScript学习笔记(二)
- JavaScript学习笔记(三)
- javaScript 学习笔记(1)
- javascript 学习笔记(3)
- javascript学习笔记(4)
- Xml解析 + Fragment + XListView +vp
- rxJava&rxAndroid-基础篇
- Atitti 知识图谱构建方法attilax 总结
- Linux 之 yum
- STL中容器的迭代器在什么情况下会失效?
- JavaScript学习笔记(12)
- iOS索引列开发详解
- 继承
- autoSave
- C语言中常见的置位操作(置0或置1)
- ISDN帧格式介绍
- 三子棋
- 第4天
- asdf