在WEB开发过程当中,咱们会常常的遇到各类事件监听以及事件处理的状况。javascript
事件(Event)即为用户的动做,例如:用户点击鼠标,产生onclick事件;按下键盘,产生onkeyDown事件;改变输入框的值,产生onchange事件...html
W3C标准规定,事件是做为函数的参数传入的,例如:前端
<p id="demo"> <a>点击我将得到节点1</a> <a>点击我将得到节点2</a> </p> <script type="text/javascript"> document.getElementById("demo").onclick=function(e) { alert(e.target); } </script>
当在元素上点击时,弹出警告框,内容为点击我将得到节点。这里函数传入的参数e,就是事件。浏览器会实时的根据用户点击的a标签的不一样返回不一样的节点内容。java
这种作法在FireFox、Chrome、Safari等遵循W3C规范的浏览器下是没有问题的,惟独在IE(暂时仅限于8.0如下版本)下是行不通的,IE采用了一种非标准的方式,并非将事件做为函数参数传入,而是将事件做为window对象的event属性:window.event传递进去的;并且,IE使用的是event.srcEvent来获取目标事件... git
既然IE8如下不行,那有什么方法解决这个问题尼?
上面其实涉及到JS事件的兼容性问题,下面咱们将从事件处理的角度来慢慢的分析这个问题。github
固然,仍是老话,全部的方法都来自网上,学到了才是本身的!!浏览器
而后,写在前面,带上咱们可爱的小伙伴。废话很少说,下面咱们开始看起吧!性能优化
文章主要是对js的this进行简单的说明和介绍,顺带会添加一些代码,没办法,语言能力有限,说明不了的只能直接上代码了。dom
IE浏览器从IE9开始已经支持DOM2事件处理程序,可是对于老版本的ie浏览器,任然使用attachEvent方式来为dom元素添加事件。值得庆幸的是微软已宣布2016年将再也不对ie8进行维护,对于广大前端开发者无疑是一个福音。然而在曙光来临以前,仍然须要对那些不支持DOM2级事件处理程序的浏览器进行兼容性处理。
嘛,下面,将慢慢的处理事件在常规状况下(额,就是W3C和IE)的处理方式。ide
借鉴GitHub上markyun写的事件侦听器函数实现。下面我只是作一些注释性说明
// event(事件)工具集,来源:https://github.com/markyun markyun.Event = { // 页面加载完成后 // 主要是原生JS,页面只能加载一次window.onload;这里使用该方法能够绑定多个方法。 readyEvent : function(fn) { if (fn==null) { fn=document; } var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = fn; } else { window.onload = function() { oldonload(); fn(); }; } }, // 视能力分别使用dom0||dom2||IE方式 来绑定事件 // 下面的顺序:标准dom2,IE dom2, dom // 参数: 操做的元素,事件名称 ,事件处理程序 addEvent : function(element, type, handler) { if (element.addEventListener) { //事件类型、须要执行的函数、是否捕捉 element.addEventListener(type, handler, false); } else if (element.attachEvent) { element.attachEvent('on' + type, function() { handler.call(element); }); } else { element['on' + type] = handler; } }, // 移除事件 removeEvent : function(element, type, handler) { if (element.removeEnentListener) { element.removeEnentListener(type, handler, false); } else if (element.datachEvent) { element.detachEvent('on' + type, handler); } else { element['on' + type] = null; } }, // 阻止事件 (主要是事件冒泡,由于IE不支持事件捕获) stopPropagation : function(ev) { if (ev.stopPropagation) { ev.stopPropagation();// 标准w3c } else { ev.cancelBubble = true;// IE } }, // 取消事件的默认行为 preventDefault : function(event) { if (event.preventDefault) { event.preventDefault();// 标准w3c } else { event.returnValue = false;// IE } }, // 获取事件目标 getTarget : function(event) { // 标准W3C 和 IE return event.target || event.srcElement; }, // 获取event对象的引用,取到事件的全部信息,确保随时能使用event; getEvent : function(e) { var ev = e || window.event; if (!ev) { var c = this.getEvent.caller; while (c) { ev = c.arguments[0]; if (ev && Event == ev.constructor) { break; } c = c.caller; } } return ev; } };
IE下的事件特例
IE下的事件对象是在window下的,而标准应该做为一个参数, 传为函数第一个参数;
IE的事件对象定义的属性跟标准的不一样,如:
cancelBubble
默认为false
, 若是为true
就是取消事件冒泡; returnValue
默认是true
,若是为false
就取消默认事件; srcElement
, 这个指的是标准W3C下的获取事件目标target
,Firefox下的也是srcElement
;
以上的全部方法,都来自网上。
全部的方法,都必须脚踏实地,在具体应用场景下去分析、去选择,咱们应该按照具体的状况,来选择方法。
由于浏览器的多样性,前端的应用场景常常很复杂,性能优化充满挑战,也充满机遇。
学会了才是本身的,知道会用会写,才是咱们最终的目标。