《JavaScript高级程序设计》之事件篇02

事件类型

规定了5中事件,UI事件、鼠标事件、键盘事件、HTML事件、变动(mutation)事件

UI事件

包含DOMActive、DOMFocusIn、DOMFoucusOut

鼠标事件

包含click、dbclick、mousedown(不能通过键盘触发)、mouseout(不能通过键盘触发)、mouseover(不能通过键盘触发)、mouseup(不能通过键盘触发)、mousemove(不能通过键盘触发)

事件执行顺序:mousedown -> mouseup -> clik -> mousedown -> mouseup -> click -> dbclick,IE8(mousedown -> mouseup -> clik -> mouseup -> dbclick)

客户区坐标位置:clientX、clientY,表示事件发生时鼠标指针在视口中的水平和垂直坐标

屏幕坐标位置:screenX、screenY,表示鼠标指针相对于整个屏幕的坐标信息

 

修改键:Shift、Ctrl、Alt、Meta,4种状态shiftKey、ctrlKey、altKey、metaKey

相关元素:只针对mouseover、mouseout两个事件,event中的relatedTarget才包含值,其他都为nul,IE不支持relatedTarget,而是mouseover时,fromElement表示相关元素,当mouseout时,toElement表示相关元素

鼠标按钮:event的button属性规定3个值:0表示主鼠标按钮,1表示鼠标滚轮、2表示次鼠标按钮,IE则提供button 8种属性值(0 1 3 5 7 对应0,2 6对应2, 4对应1)

键盘事件

keydown:当用户按下键盘上的任意键触发,按住不放,重复触发

keypress:当用户按下键盘上的字符键触发,按住不妨,重复触发

keyup:当用户释放键盘上的键触发

键码:event中的keyCode,值与ASCII中股对应小写字母或数字的编码相同

字符编码:event中的charCode,值是按下的那个键所代表的ASCII编码。检测方式是 type event.charCode == 'number'

textInput事件:DOM3级中规定。当用户在可编辑区域中输入字符时,就会触发这个事件,textInput与keypress的区别:1.keypress触发元素是任何可以获取焦点的元素,而textInput则是可编辑的区域;2.textInput只会在用户按下能够输入实际字符的键时触发,而keypress则是在按下那些能够影响文本显示的键是触发(例如退格键)

HTML事件

包含以下几种事件:

load事件:加载事件,当页面中,有图片、js文件、css文件加载之后,才会触发window的load事件,绑定方式一是window.onload,一种是body的onload属性

卸载事件unload:当文档被完全卸载后触发

resize事件:会被重复触发

scroll事件:会被重复触发

变动事件

包含以下几种:

DOMSubtreeModified — Fires when any change occurs to the DOM structure. This is a catchall event that fires after any of the other events fire.

DOMNodeInserted — Fires after a node is inserted as a child of another node.

DOMNodeRemoved — Fires before a node is removed from its parent node.

DOMNodeInsertedIntoDocument — Fires after a node has been inserted either directly or by inserting the subtree in which it exists. This event fi res after DOMNodeInserted. This event has been deprecated in DOM Level 3 Events and should not be used.

DOMNodeRemovedFromDocument — Fires before a node is removed either directly or by having the subtree in which it exists removed. This event fi res after DOMNodeRemoved. This event has been deprecated in DOM Level 3 Events and should not be used.

DOMAttrModified — Fires when an attribute has been modifi ed. This event has been deprecated in DOM Level 3 Events and should not be used.

DOMCharacterDataModified — Fires when a change is made to the value of a text node. This event has been deprecated in DOM Level 3 Events and should not be used.

专有事件

contextmenu事件:event.preventDefault(),event.returnValue = false取消默认行为

beforeunload事件:需要将event.returnValue设置为要显示给用户的字符串

mousewheel事件:支持冒泡IE(document),非IE(window),wheelDelta,向前是120的倍数,向后是-120的倍数,opera 9.5之前的版本,wheelDelta的值的正负号是相反的

DOMMouseScroll事件:firefox支持,detail属性相关信息,向前是-3的倍数,向后是3的倍数

DOMContentLoaded事件:DOM树生成之后触发,document 、window支持,可以使用setTimeout(function () {}, 0)兼容处理。

1 //DOMContentLoaded的模拟
2 EventUtil.addHandler(document, 'readystatechange', function (event) {
3     if (document.readyState == 'interactive' || document.readyState == 'complete') {
4         EventUtil.removeHandler(document, 'readystatechange', arguments.callee);
5     }
6 });

 

readystatechange事件:可以为document绑定该事件,模拟DOMContentLoaded事件,readyState的5个属性,uninitialized(未初始化),loading(正在加载),loaded(加载完毕),interactive(可以操作对象),complete(完毕)

 1 //加载外部的<script> <link>
 2 EventUtil.addHandler(window, 'load', function (event) {
 3     var script = document.createElement('script');
 4     
 5     EventUtil.addHandler(script, 'readystatechange', function (event) {
 6         event = EventUtil.getEvent(event);
 7         var target = EventUtil.getTarget(event);
 8         
 9         if (target.readyState == 'loaded' || target.readyState == 'complete') {
10             EventUtil.removeHandler(script, 'readystatechange', arguments.callee);
11         }
12     });
13     
14     script.src = 'a.js';
15     document.body.appendChild(script);
16 });

 

pageshow,pagehide事件:Firefox和Opera支持“往返缓存”(back-forward cache),可以保存页面的状态,用于浏览器的“前进”或者“后退”加快速度。pageshow是在页面显示时触发,重新加载pageshow在load后触发,对于bfcache,pageshow也会触发,绑定事件的目标绑定到window,pageshow的event对象中包含persisted属性,该属性表示页面是否存在于bfcache中,true为存在,否则为false。pagehide在浏览器卸载页面时触发,在unload之前触发。pagehide的event对象也包含persisted属性,如果页面在卸载之后被保存在bfcache中,则为true,反之为false。

移动Safari支持的事件

方向变化事件:orientationchange,orientation属性包含3个值,0表示肖像模式,90表示向左旋转模式(主屏幕按钮在右侧),-90表示向右旋转模式(主屏幕按钮在左侧)。

触摸事件:touchstart:当手指触摸屏时触发;touchmove:手指在屏幕上滑动连续触发;touchend:手指从屏幕上移开触发。触摸事件中包含了3个有用的属性:touches:表示当前跟踪的触摸操作的Touch对象数组,targetTouches:特定于事件目标的Touch对象的数组,changedTouches,表示自上次触摸后发生改变的Touch对象数组。touchmove默认行为是滚动页面。可以使用event.preventDefault取消默认行为。

手势事件:gesturestart:当一个手指已经按在屏幕,另一个手指触摸屏幕触发。gestruechange:当触摸的任何一个手指的位置发生变化时触发。gestureend:当任何一个手指离开屏幕时触发。手势事件event对象包含rotation和scale,rotation表示手指变化引起的旋转角度,负值表示逆时针旋转,正值表示顺时针旋转(从0开始)。scale表示两个手指间距的变化,从1开始。

内存和性能

事件委托

事件委托主要利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。为document绑定事件的优点:document可以很快访问到,只要可单击的元素出现,就可以生效;占用的内存更少;引用的dom更少,动态添加的dom也会绑定事件。

移除事件处理程序

问题:运行于浏览器的代码与页面交互的js建立关联;空事件处理程序;

通过innerHTML删除带有事件的dom,则绑定的事件处理程序则无法被垃圾回收。

处理方式:在innerHTML之前先移除事件处理程序(onclick = null);在onunload之前,移除所有事件处理程序;使用事件委托的方式;使用onunload事件处理程序意味着页面不会被缓存在bfcache中。

模拟事件

DOM中的事件模拟

使用createEvent()创建event对象,该方法接收一个参数,见下:

UIEvents:UI事件

MouseEvents:鼠标事件

MutationEvents:DOM变动事件

HTMLEvents:HTML事件

createEvent之后返回一个event对象,调用dom的dispatchEvent(event)来触发事件。

整个流程:createEvent -> init,事件初始化 -> dispatchEvent触发事件

 1 var btn = document.getElementById('mybtn');
 2 var event = document.createEvent('UIEvents');
 3 
 4 //3个参数,事件类型,是否冒泡,是否可以被取消
 5 event.initEvent('click', true, true);
 6 
 7 event.view = document.defaultView;
 8 event.detail = 0;
 9 event.screenX = 0;
10 event.screenY = 0;
11 event.clientX = 0;
12 event.clientY = 0;
13 ...
14 event.relatedTarget = null;
15 
16 btn.dispatchEvent(event);

 

IE中的事件模拟

创建流程:createEventObject() -> 初始化对象 ->fireEvent(事件处理程序名称,event)

 1 var btn = document.getElementById('mybtn');
 2 var event = document.createEventObject();
 3 
 4 //3个参数,事件类型,是否冒泡,是否可以被取消
 5 event.initEvent('click', true, true);
 6 
 7 event.screenX = 0;
 8 event.screenY = 0;
 9 ...
10 event.clientX = 0;
11 event.clientY = 0;
12 
13 btn.fireEvent('onclick', event);

 

posted on 2015-04-13 21:19  stonevina  阅读(212)  评论(0编辑  收藏  举报

导航