Detecting event support without browser sniffing

本文介绍了一种不依赖浏览器嗅探的可靠方法来检测浏览器是否支持特定的DOM事件。通过检查元素是否存在对应事件名称的属性或者设置事件属性后检查类型,可以有效避免因浏览器更新而导致的代码失效问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/

one of the pain points of feature testing in client-side scripting is that for  event support . DOM doesn’t really specify any means to detect exactly which events browser understands and can work with. If you’d like to know if a browser supports, say, “dblclick” event, you’re pretty much out of luck. This is probably the reason why so many scripts on the web employ  unreliable browser sniffing   in such cases. One of the most common events that people sniff for are IE’s proprietary mouseenter/mouseleave, Opera’s impotent contextmenu, and input-related onbeforepaste, onbeforecut, etc. which are present in IE and WebKit, but not in Mozilla-based browsers.

Since browser sniffing is completely unreliable (as well as unmaintainable and fragile), we need a better way to detect events.

An obvious solution might be to employ an actual testing – create an element, attach an event listener, fire an event from that element and check if event listener gets executed. This solution is unfortunately quite brittle and is often too cumbersome. Simulating key events, for example, is currently hardly supported across browsers. Moreover, many events can be considered too obtrusive and interfere with user experience. It is also possible that events such as “scroll” and “resize” are prevented by popup-blockers and so can not be reliably tested.

It’s not widely known, but there actually is a quite robust way to detect most of the DOM L2 events. The trick is that many modern browsersreport property corresponding to an event name as being existent in an element :

Unfortunately, this is not the case with Firefox. Besides, browsers that do support this, sometimes don’t allow to test an arbitrary event on an arbitrary element.  An event must be checked on an element that could actually originate that event :

To work around Firefox, we can employ a slightly different strategy (recommended by  David Mark ). The workaround is based on the fact that some of the browsers, including Firefox, actually create methods on an element  when an attribute with the name corresponding to a “known” event is set on that element :

Combining these two approaches, we can create a somewhat robust way to detect an event support. A generic  isEventSupported   function would look like:

You can now check for “contextmenu” support with –  isEventSupported("contextmenu")   – instead of an inferior –navigator.userAgent.indexOf('Opera') > -1 . If Opera “fixes” “contextmenu” event in its future versions, there’s a big chance that  isEventSupported will just evaluate to  true   and you won’t need to change a single line of code (to make whatever relies on “contextmenu” event – work)

You can also use a stripped down version of this function, for detecting, say, only Mouse events:

And then use –  isMouseEventSupported("mouseenter")   instead of a horrendous –  (!!window.attachEvent && !window.opera)   :)

The only oddity I noticed with this method was IE reporting  false   for “unload” event. “unload” can still be easily checked in a global  window object –  "unload" in window   – returns  true   in all versions of IE that I tested (6-8). That expression can, of course, produce false positives if there’s a global “unload” variable, but, as a workaround, you can always try deleting the variable and see if  in   still returns  true .

A minor downside to this test is that it doesn’t allow to detect  Mutation Events . Fortunately, detecting those is not very complex. You can find an example of  a perfect feature test for DOMAttrModified   in Diego Perini’s NWMatcher.

I made  a simple test case , listing all of the events specified in DOM L2 and corresponding results of running  isEventSupported   on them.

Give it a try, and enjoy a feature testing!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值