比如musewheel事件,如何检测在当前浏览器的实现中是否可以使用?如果使用类似document.onmousewheel这样的方式,如何避免这个方法被人恶意(重)定义?
2 回答
阿晨1998
TA贡献2037条经验 获得超6个赞
楼上的给出了一段封装好的代码,我尝试讲一下思路什么的。在大多数的现代浏览器中,你可以通过下面的方式检测在当前浏览器中是否可以用这个事件:'onclick'indocument.documentElement;嗯,前面说了这段代码只是在大多数浏览器中可用,并不是所有的浏览器中都靠谱。为什么,因为可能会用到一些偏门的事件,比如只有IE支持的mouseenter,mouseleave,onpropertychange什么的,IE9-中没有oninput事件什么的,或者还有一些其他浏览器中才有的事件等等。这本身就取决于浏览器对标准的实现,和自身的实现。经评论中@依云的补充,测试发现现代浏览器都兼容了mouseenter,mouseleave事件。上面这种方法不靠谱,那就另辟蹊径,尽量进行可靠的测试。比如reset事件通常用于表单重置操作,事实上在某些浏览器下面直接检测document.documentElement-文档是否支持的时候可能不同的浏览器结果不同。而这个时候可以尝试检测特定的元素是否支持这个事件。毕竟可以粗略的说,在浏览器中事件大部分情况都是用在DOM元素上的。因此,可以还可以这样检测:'onreset'indocument.createElement('input')通常情况下直接尝试查看浏览器的event属性的类型会发现它会返回字符串'function',便于测试,还可以这样:vardom=document.createElement('div');dom.setAttribute('onclick','xxx');//保险起见,设置浏览器可能已知的事件类型来测试它typeofdom.onclick;//->'function',测试浏览器已知事件类型的时候通常覆写没用,它会正确的返回内置属性//也可以换个自定义的事件使用这种方式尝试检测根据上面这些结论,就可以定义一个通用的函数来检测浏览器是否支持特定的事件了:functiondetectEventSupport(eventName){vartempElement=document.createElement('div'),isSupported;eventName='on'+eventName;isSupported=(eventNameintempElement);//使用第一种方式//如果第一种方式行不通,那就来看看它是不是已知事件类型if(!isSupported){tempElement.setAttribute(eventName,'xxx');isSupported=typeoftempElement[eventName]==='function';}//清除掉动态创建的元素,以便内存回收tempElement=null;//返回检测结果returnisSupported;}至此,一个基本靠谱的测试函数就完备了。楼上的代码中有个TAGNAMES,然后在后面的检测中用到了。这里实际上只是为了保证测试的完备性和健壮性,列出了一部分已知在这些元素上支持的事件进行测试。写在最后,正如上面所说。因为可能会用到某些浏览器厂商自定义的事件类型什么的,这种情况下最好查查规范,查查浏览器相关的文档,以确保测试的准确性。而对于多数标准的浏览器事件,上面的方法是能够进行可靠检测的。万一碰到无法确认的,查文档;针对特定的环境进行检测即可,思路有了就好办了。补充修正:比如楼上的Modernizr的代码中提供的事件并不一定要每个都进行判断。这些事件浏览器都是支持的。在前面的代码中,都是直接对document对象或者div元素进行测试,可能需要处理的元素并不是div,那么针对特定的元素进行处理即可。使用keyinobject的方式进行检测的时候很容易受自定义事件的影响,比如:document.onxxx='xxx';'onxxx'indocument;这种情况下keyinobject就显得不那么可靠了。解释下上面第三种方式,为什么先setAttribute,再用ele[eventName]的方式检测。在标准中规定,使用setAttribute()方法添加已有的属性时会重写指定的属性值。但是事实上,在用这个方法设置已有的事件属性时,然后直接用ele[eventName]访问这个属性,始终返回的是已有的事件属性,而事件属性对应的实现都是function。因而基于这种方式,检测已知事件属性类型时总是返回'function'。
三国纷争
TA贡献1804条经验 获得超7个赞
先回答前一个问题。可以参考Modernizr的处理方式:functionis(obj,type){returntypeofobj===type;}varisEventSupported=(function(){varTAGNAMES={'select':'input','change':'input','submit':'form','reset':'form','error':'img','load':'img','abort':'img'};functionisEventSupported(eventName,element){element=element||document.createElement(TAGNAMES[eventName]||'div');eventName='on'+eventName;varisSupported=eventNameinelement;if(!isSupported){if(!element.setAttribute){element=document.createElement('div');}if(element.setAttribute&&element.removeAttribute){element.setAttribute(eventName,'');isSupported=is(element[eventName],'function');if(!is(element[eventName],'undefined')){element[eventName]=undefined;}element.removeAttribute(eventName);}}element=null;returnisSupported;}returnisEventSupported;})();isEventSupported("mousewheel")//Chrome->trueisEventSupported("mousewheel")//Firefox->false
添加回答
举报
0/150
提交
取消
