支持DOM0、DOM2的浏览器和IE浏览器实现事件处理程序的不一样,除了体如今添加事件处理程序的不一样上,还体如今event对象的实现差别上,包括具体的属性和方法。
在触发DOM上的某个事件时,都会产生一个event对象,这个对象包含着全部与事件有关的信息。一旦事件处理程序执行完成,event对象就会被销毁。全部浏览器对event的支持方式包括:DOM事件对象和IE事件对象。javascript
兼容 DOM 的浏览器会将一个 event 对象传入到事件处理程序中。不管指定事件处理程序时使用什么方法(DOM0 级或 DOM2 级) ,都会传入 event 对象。java
var btn = document.getElementById("myBtn"); btn.onclick = function(event){ alert(event.type); //"click" }; btn.addEventListener("click", function(event){ alert(event.type); //"click" }, false);
在经过 HTML 特性指定事件处理程序时,变量 event 中保存着 event 对象:web
<input type="button" value="Click Me" onclick="alert(event.type)"/>
(1) type, String; 只读; 被触发的事件的类型,如click。
(2) currentTarget, Element,只读,其事件处理程序当前正在处理事件的那个元素;
(3) target, Element, 只读, 事件的目标;
在事件处理程序内部,对象 this 始终等于 currentTarget 的值(注册事件处理程序的元素),而 target 则只包含事件的实际目标(事件直接触发的元素)。若是直接将事件处理程序指定给了目标元素,则 this、 currentTarget 和 target 包含相同的值。可是考虑到有时候会使用事件冒泡机制,事件直接触发的元素不必定是事件绑定的元素,例如:浏览器
//按钮在body中,事件会冒泡到body document.body.onclick = function(event){ alert(event.currentTarget === document.body); //true alert(this === document.body); //true alert(event.target === document.getElementById("myBtn")); //true };
当单击这个例子中的按钮时, this 和 currentTarget 都等于 document.body,由于事件处理程序是注册到这个元素上的。然而, target 元素却等于按钮元素,由于它是 click 事件真正的目标。因为按钮上并无注册事件处理程序,结果 click 事件就冒泡到了 document.body,在那里事件才获得了处理。安全
(4) preventDefault()方法:阻止特定事件的默认行为。例如,连接的默认行为就是在被单击时会导航到其 href 特性指定的 URL。app
var link = document.getElementById("myLink"); link.onclick = function(event){ event.preventDefault(); };
(5) stopPropagation()方法:用于当即中止事件在 DOM 层次中的传播,即取消进一步的事件捕获或冒泡。这个属性在jQuery中很重要。函数
(6) eventPhase 属性:能够用来肯定事件当前正位于事件流的哪一个阶段。若是是在捕获阶段调用的事件处理程序,那么 eventPhase 等于 1;若是事件处理程序处于目标对象(直接点击对象,通常是最内层对象)上,则 eventPhase 等于 2;若是是在冒泡阶段调用的事件处理程序, eventPhase 等于 3。这里要注意的是,尽管“处于目标”发生在冒泡阶段,但 eventPhase 仍然一直等于 2。测试
var btn = document.getElementById("myBtn"); btn.onclick = function(event){ alert(event.eventPhase); //2 ,最内元素在事件传播结束后触发 }; document.body.addEventListener("click", function(event){ alert(event.eventPhase); //1,DOM2事件触发使用true参数是在传播阶段触发 }, true); document.body.onclick = function(event){ alert(event.eventPhase); //3,DOM0事件在冒泡阶段触发 };
当单击这个例子中的按钮时,首先执行的事件处理程序是在捕获阶段触发的添加到 document.body中的那一个,结果会弹出一个警告框显示表示 eventPhase 的 1。接着,会触发在按钮上注册的事件处理程序,此时的 eventPhase 值为 2。最后一个被触发的事件处理程序,是在冒泡阶段执行的添加到document.body 上的那一个,显示 eventPhase 的值为 3。而当 eventPhase 等于 2 时,this、target和 currentTarget 始终都是相等的。this
IE中event对象的访问方式取决于绑定事件处理程序的方法:
1)DOM0级方法: event对象做为window对象的一个属性存在。spa
var btn = document.getElementById("myBtn"); btn.onclick = function(){ var event = window.event; alert(event.type); //"click" };
2)若是事件处理程序是经过attachEvent()添加的,就有一个event对象做为事件处理程序的参数。
var btn = document.getElementById("myBtn"); alert(typeof attachEvent); btn. attachEvent("click", function(event){ alert(event.type); //"click" });
1)cancelBubble:默认值为false,但将其设置为true就能够取消事件冒泡(与DOM中
的stopPropagation()方法的做用相同);
2)returnValue:默认值为true,但将其设置为false就能够取消事件的默认行为(与
DOM中的preventDefault()方法的做用相同);
3)srcElement:事件的直接目标(与DOM中的target属性相同);
4)type:被触发的事件的类型。
srcElement:由于事件处理程序的做用域是根据指定它的方式来肯定的, this 不必定老是等于事件目标。例如:
var btn = document.getElementById("myBtn"); btn.onclick = function(){ alert(window.event.srcElement === this); //DOM0级方法,true }; btn.attachEvent("onclick", function(event){ alert(event.srcElement === this); //false });
returnValue 属性:只要将 returnValue 设置为 false,就能够阻止默认行为。
var link = document.getElementById("myLink"); link.onclick = function(){ window.event.returnValue = false; };
cancelBubble 属性:与 DOM 中的 stopPropagation()方法做用相同,都是用来中止事件冒泡的。因为 IE 不支持事件捕获,于是只能取消事件冒泡;但 stopPropagatioin()能够同时取消事件捕获和冒泡。例如:
//在单击按钮以后,只会显示一个警告框。 var btn = document.getElementById("myBtn"); btn.onclick = function(){ alert("Clicked"); window.event.cancelBubble = true; }; document.body.onclick = function(){ alert("Body clicked"); };
可是在IE11发布以后attachEvent函数被替换成了addEventListener。
var btn = document.getElementById("myBtn"); alert(typeof addEventListener);//function btn.addEventListener("click", function(event){ alert(event.type); //"click" });
IE11中srcElement属性测试:
HTML:
<div id="wrapper"> <span id = "myBtn">the onlt one div</span> </div>
JavaScript:
var wrapper = document.getElementById("wrapper"); alert(typeof addEventListener); wrapper.addEventListener("click", function(event){ alert(event.target); //span alert(event.currentTarget); //div alert(event.srcElement); //span alert(this);//div });
结论:srcElement和target是相同的,都指向事件的直接元素,可是this和currentTarget都指向事件绑定元素。
若是须要阻止默认行为,直接使用在addEventListener()中使用event.preventDefault()便可。根据以上,能够得出初步的结论:在IE11浏览器中使用addEventListener()后,DOM2级event具备的属性和方法均可以使用。
我在IE中使用addEventListener()并无遇到问题,可是网上有一些开发者在使用时会遇到问题,提供的解决方法有数种:
https://social.msdn.microsoft...
第一种是加入一些脚本:
<script language='javascript' for="testAxEvent" event="testEvent(szType, szValue)"> // Test 1 - statically load the script (This is the basis for the hack) // Works on IE8, IE9, IE10 and IE11 var MSG = document.getElementById("msg"); MSG.innerHTML = szType + " : " + szValue; </script>
第二种是把IE的internet选项-- >安全,点击“将全部区域重置为默认级别”。
var EventUtil = { //是否支持DOM2?是不是IE?是否支持DOM0?通常前两个if包含了全部状况 addHandler: function(element, type, handler){ if (element.addEventListener){ element.addEventListener(type, handler, false); } else if (element.attachEvent){ element.attachEvent("on" + type, handler); } else { element["on" + type] = handler; } }, //IE没有event对象,所以使用window.event getEvent: function(event){ return event ? event : window.event; }, /*使用getEvent()方法获得event对象后才可使用getTarget()、 preventDefault()、stopPropagation()方法 */ //先检测DOM0 DOM2的target属性,而后检测IE的srcElement属性 getTarget: function(event){ return event.target || event.srcElement; }, //先检测DOM0 DOM2的preventDefault(),再检测IE的returnValue preventDefault: function(event){ if (event.preventDefault){ event.preventDefault(); } else { event.returnValue = false; } }, //是否支持DOM2?是不是IE?是否支持DOM0?通常前两个if包含了全部状况 removeHandler: function(element, type, handler){ if (element.removeEventListener){ element.removeEventListener(type, handler, false); } else if (element.detachEvent){ element.detachEvent("on" + type, handler); } else { element["on" + type] = null; } }, //先检测DOM0 DOM2的stopPropagation(),再检测IE的cancelBubble stopPropagation: function(event){ if (event.stopPropagation){ event.stopPropagation(); } else { event.cancelBubble = true; } } };
测试实例:
var but = document.getElementById("myButtun"); var handler = function(event){ event = EventUtil.getEvent(event); var target = EventUtil.getTarget(event); alert(target);// [object HTMLInputElement] }; EventUtil.addHandler(but, "click", handler);
固然,上述跨浏览器的事件对象所包含的属性和方法并非必须的,在实际中能够根据实际状况适当删减一些属性和方法。可是,万变不离其宗。