简体   繁体   中英

Why does getPreventDefault() work but defaultPrevented doesn't?

I'm working on a Firefox extension, and I keep seeing the following warning:

Use of getPreventDefault() is deprecated. Use defaultPrevented instead.

However, for what I'm trying to do it seems that defaultPrevented doesn't work, while getPreventDefault() does. For a simplified code snippet, here's what I put into my Firefox browser scratchpad while running in the Browser context:

window.addEventListener('fooEvent', function (event) { 
    console.log('fooEvent has fired');
    event.preventDefault();
}, true, true);

So then in my browser console (the one I get when hitting Shift+Ctrl+k) I run the following code:

e = document.createEvent('Event');
e.initEvent('fooEvent', true, true);
document.dispatchEvent(e);
console.log('after dispatch', e.defaultPrevented, e.getPreventDefault());

I can see the fooEvent has fired message in my Javascript console, so I know the event was caught. But I see the message after dispatch false true which indicates that defaultPrevented is still false while getPreventDefault() is correctly returning true. But Firefox still displays the deprecation warning!

I'd like to avoid using a deprecated API call because I don't want a Firefox upgrade to break my extension. (There's an open ticket for the deprecated API call to be removed, though it looks like it'll probably be awhile before it's completed.) What am I doing wrong?

I can reproduce this in Firefox 30 and Nightly.

What you have discovered here seems to be a genuine bug when it comes to handling synthetic content events from privileged code.

To answer your question: You don't seem to do anything wrong; the browser is. Use getDefaultPrevented() for the time being and while it is still available. You can feature-detect (and hope that .defaultPrevented will be fixed before .getPreventDefault() is removed):

var dp = "getPreventDefault" in e ?
  e.getPreventDefault() :
  e.defaultPrevented;

As the one who discovered this bug, please file a bug and block it against https://bugzilla.mozilla.org/show_bug.cgi?id=691151

It would be great if you provided the new bug URI in a comment or something. If you don't want to file yourself, please say so and I will file it for you.

Edit

Another way to deal with it is to use the result of dispatchEvent() . Apparantly the mozilla folks forgot to break it, too.

The return value of dispatchEvent indicates whether any of the listeners which handled the event called preventDefault. If preventDefault was called the value is false, else the value is true.

from: DOM-Level-2-Events

e = document.createEvent('Event');
e.initEvent('fooEvent', true, true);
if (document.dispatchEvent(e)) {
  // Execute default action
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM