EventHandler事件处理器2---跨浏览器事件对象《高程3》
时间:2023-04-02 22:14:49
HTML
0Event对象介绍支持DOM0、DOM2浏览器和IE浏览器实现不同的事件处理器,除了添加事件处理器的区别外,还体现在事件对象的实现差异,包括具体的属性和方法。当DOM上的事件被触发时,会生成一个事件对象,其中包含与该事件相关的所有信息。一旦事件处理程序完成执行,事件对象就会被销毁。所有浏览器对事件的支持方法包括:DOM事件对象和IE事件对象。1.1DOM0和DOM2支持的事件对象(适用于除IE以外的浏览器)兼容DOM的浏览器会将事件对象传递给事件处理程序。指定事件处理程序时,无论使用何种方法(DOM0级或DOM2级),都会传入事件对象。varbtn=document.getElementById("myBtn");btn.onclick=function(event){alert(event.type);//“点击”};btn.addEventListener(“点击”,function(event){alert(event.type);//“点击”},false);通过HTML特性指定事件处理器时,事件对象存储在变量event中:1.2常用属性和方法事件对象(1)类型,String;只读;被触发的事件类型,例如点击。(2)currentTarget,Element,只读,其事件处理程序当前正在处理事件的元素;(3)target,Element,只读,事件的目标;在事件处理程序内部,对象this始终等于currentTarget(注册事件处理程序的元素)的值,而target仅包含事件的实际目标(事件直接触发的元素)。如果事件处理程序直接分配给目标元素,则this、currentTarget和target包含相同的值。但是考虑到有时会使用事件冒泡机制,事件直接触发的元素不一定是事件绑定的元素,例如://按钮在body中,事件会向上冒泡到bodydocument.body.onclick=function(event){alert(event.currentTarget===document.body);//truealert(this===document.body);//truealert(event.target===document.getElementById("myBtn"));//真的};单击此示例中的按钮时,this和currentTarget都等于document.body,因为事件处理程序已注册到此元素。但是,目标元素等同于按钮元素,因为它是点击事件的实际目标。由于没有在按钮上注册事件处理程序,因此单击事件冒泡到document.body,并在那里进行处理。(4)preventDefault()方法:防止特定事件的默认行为。例如,链接的默认行为是在单击时导航到其href属性指定的URL。varlink=document.getElementById("myLink");link.onclick=function(event){event.preventDefault();};(5)stopPropagation()方法:用于立即停止事件在DOM层级中的传播,即取消进一步的事件捕获或冒泡。这个属性在jQuery中很重要。(6)eventPhase属性:可以用来判断事件当前在事件流中处于哪个阶段。如果在捕获阶段调用事件处理器,则eventPhase等于1;如果事件处理器在目标对象上(直接点击对象,通常是最里面的对象),那么eventPhase等于2;如果它是在冒泡阶段调用的事件处理程序,eventPhase等于3。这里需要注意的是,即使在冒泡阶段发生了“ontarget”,eventPhase始终等于2。varbtn=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总是相等的。2.1IE中的事件对象IE中事件对象的访问方式取决于绑定事件处理器的方法:1)DOM0级方法:事件对象作为窗口对象的属性存在。varbtn=document.getElementById("myBtn");btn.onclick=function(){varevent=window.event;警报(事件类型);//“点击”};2)如果事件处理程序是通过attachEvent()添加的,则有一个事件对象作为事件处理程序的参数。varbtn=document.getElementById("myBtn");警报(附加事件类型);btn.attachEvent("click",function(event){alert(event.type);//"click"});2.2IE中事件对象的属性和方法1)cancelBubble:默认值为false,但设置为true可以取消事件冒泡(与DOM中的stopPropagation()方法功能相同);2)returnValue:默认值为true,但是设置为false可以取消事件的默认行为(同DOM中的preventDefault()方法);3)srcElement:事件的直接目标(同DOM中的target属性);4)type:触发事件的类型。srcElement:因为事件处理程序的范围取决于它的指定方式,所以这可能并不总是等于事件目标。例如:varbtn=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,就可以防止默认行为。varlink=document.getElementById("myLink");link.onclick=function(){window.event.returnValue=false;};cancelBubble属性:与DOM中的stopPropagation()方法功能相同,均用于停止事件冒泡。由于IE不支持事件捕获,只能取消事件冒泡;但是stopPropagatioin()可以同时取消事件捕获和冒泡。示例://单击按钮后,只会显示一个警告框。varbtn=document.getElementById("myBtn");btn.onclick=function(){alert("Clicked");window.event.cancelBubble=true;};document.body.onclick=function(){alert("Bodyclicked");};2.3IE11的变化但是在IE11发布之后,attachEvent函数被addEventListener所取代。varbtn=document.getElementById("myBtn");alert(typeofaddEventListener);//functionbtn.addEventListener("click",function(event){alert(event.type);//"click"});在IE11srcElement属性测试中:HTML:onltonediv
JavaScript:varwrapper=document.getElementById("wrapper");警报(类型的addEventListener);wrapper.addEventListener("click",function(event){alert(event.target);//spanalert(event.currentTarget);//divalert(event.srcElement);//spanalert(this);//分区});结论:srcElement和target一样,都是指向事件的直接元素,但是this和currentTarget都指向事件绑定元素。如果需要阻止默认行为,可以直接在addEventListener()中使用event.preventDefault()。综上所述,可以得出一个初步的结论:在IE11浏览器中使用addEventListener()后,DOM2级别事件的所有属性和方法都可以使用。我在IE中使用addEventListener()没问题,但是网上有一些开发者在使用的时候遇到了问题,提供了几种解决方法:https://social.msdn.microsoft...第一种是添加一些scripts:其次是设置IE的internet选项-->安全,点击“将所有区域重置为默认级别”。3跨浏览器事件对象EventUtilvarEventUtil={//是否支持DOM2?是IE吗?你支持DOM0吗?一般前两个if包含所有情况addHandler:}elseif(element.attachEvent){element.attachEvent("on"+type,handler);}else{element["on"+type]=handler;}},//IE没有事件对象,所以使用window.eventgetEvent:function(event){returnevent?事件:窗口事件;},/*在使用getTarget(),preventDefault(),stopPropagation()方法之前先使用getEvent()方法获取事件对象*///先检测DOM0DOM2的t??arget属性,再检测DOM2的srcElement属性IEgetTarget:function(event){返回event.target||.preventDefault){事件.preventDefault();}else{event.returnValue=false;}},//是否支持DOM2?是IE吗?你支持DOM0吗?通常,前两个if涵盖所有情况removeHandler:}elseif(element.detachEvent){element.detachEvent("on"+type,handler);}else{element["on"+type]=null;}},//先检测DOM0和DOM2的stopPropagation(),再检测IE的cancelBubblestopPropagation:function(event){if(event.stopPropagation){event.stopPropagation();}else{event.cancelBubble=true;}}};测试实例:varbut=document.getElementById("myButtun");varhandler=function(event){event=EventUtil.getEvent(event);vartarget=EventUtil.getT目标(事件);alert(target);//[对象HTMLInputElement]};EventUtil.addHandler(but,"click",handler);当然,上述跨浏览器事件对象中包含的属性和方法并不是必须的,实际中可以根据实际情况适当删除一些属性和方法。但是,一切都保持不变。