比如musewheel事件,如何检测在当前浏览器的实现中是否可以使用?
如果使用类似document.onmousewheel这样的方式,如何避免这个方法被人恶意(重)定义?
比如musewheel事件,如何检测在当前浏览器的实现中是否可以使用?
如果使用类似document.onmousewheel这样的方式,如何避免这个方法被人恶意(重)定义?
先回答前一个问题。
可以参考Modernizr的处理方式:
function is( obj, type ) {
return typeof obj === type;
}
var isEventSupported = (function() {
var TAGNAMES = {
'select': 'input', 'change': 'input',
'submit': 'form', 'reset': 'form',
'error': 'img', 'load': 'img', 'abort': 'img'
};
function isEventSupported( eventName, element ) {
element = element || document.createElement(TAGNAMES[eventName] || 'div');
eventName = 'on' + eventName;
var isSupported = eventName in element;
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;
return isSupported;
}
return isEventSupported;
})();
isEventSupported("mousewheel")// Chrome
-> true
isEventSupported("mousewheel")// Firefox
-> false
13 回答12.8k 阅读
8 回答2.6k 阅读
2 回答5.1k 阅读✓ 已解决
7 回答1.9k 阅读
3 回答2.2k 阅读✓ 已解决
5 回答857 阅读
3 回答1.1k 阅读✓ 已解决
楼上的给出了一段封装好的代码,我尝试讲一下思路什么的。
在大多数的现代浏览器中,你可以通过下面的方式检测在当前浏览器中是否可以用这个事件:
嗯,前面说了这段代码只是在大多数浏览器中可用,并不是所有的浏览器中都靠谱。为什么,因为可能会用到一些偏门的事件,比如只有IE支持的
mouseenter
,mouseleave
,onpropertychange
什么的,IE9-中没有oninput
事件什么的,或者还有一些其他浏览器中才有的事件等等。这本身就取决于浏览器对标准的实现,和自身的实现。上面这种方法不靠谱,那就另辟蹊径,尽量进行可靠的测试。比如
reset
事件通常用于表单重置操作,事实上在某些浏览器下面直接检测document.documentElement
- 文档是否支持的时候可能不同的浏览器结果不同。而这个时候可以尝试检测特定的元素是否支持这个事件。毕竟可以粗略的说,在浏览器中事件大部分情况都是用在DOM
元素上的。因此,可以还可以这样检测:通常情况下直接尝试查看浏览器的
event
属性的类型会发现它会返回字符串'function'
,便于测试,还可以这样:根据上面这些结论,就可以定义一个通用的函数来检测浏览器是否支持特定的事件了:
至此,一个基本靠谱的测试函数就完备了。
楼上的代码中有个
TAGNAMES
,然后在后面的检测中用到了。这里实际上只是为了保证测试的完备性和健壮性,列出了一部分已知在这些元素上支持的事件进行测试。写在最后,正如上面所说。因为可能会用到某些浏览器厂商自定义的事件类型什么的,这种情况下最好查查规范,查查浏览器相关的文档,以确保测试的准确性。而对于多数标准的浏览器事件,上面的方法是能够进行可靠检测的。万一碰到无法确认的,查文档;针对特定的环境进行检测即可,思路有了就好办了。
补充修正:
document
对象或者div
元素进行测试,可能需要处理的元素并不是div
,那么针对特定的元素进行处理即可。key in object
的方式进行检测的时候很容易受自定义事件的影响,比如:这种情况下
key in object
就显得不那么可靠了。解释下上面第三种方式,为什么先
setAttribute
,再用ele[eventName]
的方式检测。在标准中规定,使用setAttribute()
方法添加已有的属性时会重写指定的属性值。但是事实上,在用这个方法设置已有的事件属性时,然后直接用ele[eventName]
访问这个属性,始终返回的是已有的事件属性,而事件属性对应的实现都是function
。因而基于这种方式,检测已知事件属性类型时总是返回
'function'
。