再谈浏览器事件

事件绑定与事件获取

说起浏览器事件,就不得不说绑定事件的方式,或者说事件的处理。在现代浏览器与IE8及以下的浏览器中,事件绑定方式是不同的。

现代浏览器绑定事件:

DOM.addEventListener('eventName', handler, capture[Boolean])

古老IE绑定事件(IE8及以下):

DOM.attachEvent('on(eventName)'[String], handler[function])

而两者都支持DOM level0 绑定事件方式:

DOM.onclick = function(){}

一般想要在事件处理函数中获得当前的事件对象进行一系列判断与操作,那么在不同的浏览器下,获取事件对象也不相同。现代浏览器获取事件对象可以直接在事件处理函数中获得函数的第一个实参,该参数即为当前的事件对象:

DOM.on*** = function(e){ e即为事件对象 }
DOM.addEventListenter('eventName'[String], function(e){ e即为事件对象 }, capture[Boolean])

而在古老IE下,事件处理函数的第一个实参是未定义的,而你可以使用window.event来获取:

DOM.attachEvent(function(e){ e是未定义的,可以使用window.event来获取 })

事件处理中的 this

在addEventListener及level0的事件处理函数中,this都是指向绑定的dom对象,而在古老ie的attache绑定的函数中,this则是指向全局上下文中的window对象。

target、srcElement、currentTarget

通过事件对象是可以获取到触发该事件的dom元素的,不过在不同浏览器下,获取的方式也不一样。标准情况下,通过事件对象的 target 属性可以获取到当前响应的dom元素,不过在IE下,只能使用srcElement来获取,chrome是两者都支持的。还有 currentTarget 属性,该属性与 target 不同的是,它直接指向事件的绑定对象,而不会获取冒泡过程中的元素,比如有一个<div>嵌套另一个<p>, 我们对<p>绑定click事件,<p>充满整个div,当点击<div>的时候毫无疑问也会触发事件,只不过此时的事件对象target指向的是这个<div>,而currentTarget一直指向的都是<p>本身。

阻止事件冒泡

e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = true);

阻止事件默认行为

e.preventDefault ? e.preventDefault() : (e.returnValue = false);

避免冒泡处理(注意:不是取消冒泡)

在开发过程中,想要避免冒泡获取事件的需求常有,focus, blur,ie下有focusin等都是不会冒泡的事件,而在现代浏览器中可以采用事件捕捉的形式来避免冒泡。

自定义事件

自定义事件也是非常常见的需求,前几天还在一次移动开发中遇到了自定义事件兼容性的问题,导致安卓手机大面积无法使用。

定义自定义事件

首先是支持度比较好的自定义事件定义方式:

var evtSwipeTop = document.createEvent('HTMLEvents');
evtSwipeTop.initEvent('eventname', false, false);

还有一种比较简单的定义方式,但是支持度很差,手机端也是如此:

var evtSwipeBottom = new Event('pages.toBottom');

绑定自定义事件

定义好之后,绑定自定义事件很简单:

DOMElement.addEventListener('eventname', handler, false);

触发自定义事件

DOMElement.dispatchEvent(eventObject); // 注意,参数是定义的event object