Helpful Information
 
 
Category: Client side development
Detecting support for an event handler?

Does anyone know if it's possible to detect support for an event handler in JavaScript? Obviously you can do so for properties or methods, but the logistics of JS seems to imply you can't do the same for events.

Specifically, I'm trying to detect support for the event:

document.oncontextmenu

Thanks,

Well, you can check for support of any DOM2 HTML event via:
document.implementation.hasFeature('HTMLEvents', '2.0')

which returns a boolean true/false corresponding to the browser's support.

Mozilla 1.0 returns true on that, IE 6 false.

But of course, the oncontextmenu is a proprietary handler originally implemented by IE5+ (maybe?), and eventually supported in Mozilla as well, so you'll just need some good old-fashioned browser detection for now:

var supportsContextMenuEvent = (navigator.appName.indexOf('Microsoft') == 0 && parseFloat(navigator.userAgent.substring(30,33)) >= 5) || (navigator.appName.indexOf('Netscape') == 0 && parseFloat(navigator.appVersion) >= 5);

I am unaware of any other way to detect support for proprietary events.

jason, stop me if i'm wrong, but event handlers are properties of objects. eg, document.onmouseover, is a property of document. which means, in theory, you could do a plain old if (document.oncontextmenu) {} . might be worth giving a shot.

Hi guys;
Thanks for the responses. Apparently just using:

document.oncontextmenu

as the detection doesn't work, as events are not initialized unless specifically invoked. So document.oncontextmenu will by default return null even in browsers that support it such as IE5.5.

Anyhow, the reason for my question is because some very early versions of NS6 do not support document.contextmenu. Using the navigator object is both a pain and may not be refined enough in this case to sniff out such browsers...

joh6nn, George is mostly right. Unless you explicitly assign the event handler a function, it returns undefined, not null.

You could do some crazy stuff though, like watch() a property on a div, and change that property on the oncontextmenu event, then have progmatically fire that event on the div through JS (not sure if Mozilla let's you fire contextmenu though...), then check to see if it happened, and voila - you know your support. Easy as that ;).

George - good news! I almost have a crossbrowser function ready that checks for support of events - will post it when done. :)

George, bad news. :D
I can fire every single event in the world, except for contextmenu in Mozilla. :o

Here is what the final code is shaping up to be:


function supportsEvent(event) {
function verify() {
supportsEvent.does = true;
}
supportsEvent.does = false;

try {
if (typeof document.fireEvent != 'undefined') {
document.attachEvent(event, verify);
document.fireEvent(event);
document.detachEvent(event, verify);
}
else if (typeof document.createEvent != 'undefined') {
document.addEventListener(event.substr(2), verify, true);
var evt = document.createEvent('Events');
evt.initEvent(event.substr(2), false, false);
document.dispatchEvent(evt);
document.removeEventListener(event.substr(2), verify, true);
}
}
catch (e) {};

return supportsEvent.does;
}


Now, you would use it like:

supportsEvent('eventname')

which returns a boolean true/false.

The W3C DOM specs require though that if a mouse event is specified (onmousemove, onmouseout, etc), I need to call initMouseEvent instead of initEvent. Same goes for MutationEvents, KeyEvents, UIEvents, etc.
Ultimately, I'm going to have a switch statement in the Mozilla part of the code.

An interesting thing I learned from this though is that Mozilla supports custom events.

Essentially, I can fire "onmycustomevent" and if any event listener's were set to that event, the appropriate function is fired.

After all that though, I'm still looking around for the correct way to fire the oncontextmenu event... I'll post a finalized function here when I get it. :)

Or if you know exactly which IE versions support d.onctext you
could look for something proprietary for those browsers. eg

if (document.recalc) { // IE5+ }

Jkd:
It seems you're using DOM features to do the detection, which means it wouldn't work in older browsers?

One thing I've been thinking is taking advantage of the natural downwards degradability of events. For example:

document.oncontextmenu=new Function ("alert('hi')")

would only alert a message in browsers that support oncontextmenu; in other browsers, a string(?) value would be set instead. Perhaps one solution would be to probe the event's value to see if the browser supports this event...

well, maybe i'm being stupid, but is testing for it really necessary? if it's not supported, then all that happens, is that the document object receives a method that it never uses, instead of an event handler. in most cases, that sort of degradation is fine, i think. but that's all without knowing what you want it for.










privacy (GDPR)