[webkit-dev] focusin/focusout events

Ojan Vafai ojan at chromium.org
Wed Jul 21 17:24:38 PDT 2010


WebKit doesn't match the DOM 3 spec WRT focusin/focusout events, see
http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-focusevent-doc-focus
. Specifically, focusin/focusout are supposed to fire before the element
actually receives/loses focus. Browsers are wildly inconsistent with
focus-related events, but only WebKit and IE support focusin/focusout and
only WebKit gets this bit wrong.

Also, there are a few things that you ought to be able to do that you can't
currently:
1. Capture and handle a blur-type event before focus is moved or the
selection is cleared/moved.
2. Capture and handle a focus-type event before focus is moved or the
selection is cleared/moved.

In WebKit, the selection and focus are cleared from the element being
blurred before any events are fired. That's lametastic. One common use-case
here is making keyboard-accessible UI widgets for a rich-text area. For
keyboard-accessible UI widgets, especially ones that require text input
(e.g. a font combo-box), you need to save the selection before blurring.
Instead of simply listening to a blur event, you need to instrument every
place that might clear the selection when clicked in order to save it first.

I've listed below the order events are fired in different browsers when one
element is blurred and another is focused.

I was using roughly this code:
<div contentEditable id=foo>asdf</div>
<div contentEditable id=bar>qwer</div>
<script>
var foo = document.getElementById('foo');
var bar = document.getElementById('bar');
bar.addEventListener('DOMFocusIn', function() { console.log('focusin: ' +
document.activeElement.id) }, true);
bar.addEventListener('focus', function() { console.log('focus: ' +
document.activeElement.id) }, true);
foo.addEventListener('DOMFocusOut', function() { console.log('focusout: ' +
document.activeElement.id) }, true);
foo.addEventListener('blur', function() { console.log('blur: ' +
document.activeElement.id) }, true);
</script>

Opera 10.6: blur, domfocusout, focus, domfocusin
Moves activeElement immediately before firing any events.

WebKit nightly: blur, (dom)focusout, focus, (dom)focusin
Clears activeElement before blur/focusout, sets active element before
focus/focusin

FF 3.6:blur, focus
Clears activeElement before blur, sets active element before focus.

IE 8: focusout, focusin, blur, focus
Moves activeElement immediately before firing any events.

It's a bit gross, but the only solution I can think of is to fire the
following events in WebKit (in this order):
focusout
focusin
{remove focus and clear selection as appropriate}
blur
domfocusout
{add focus to new node and set selection as appropriate}
focus
domfocusin

I'd like to say we could get rid of DOMFocusOut/DOMFocusIn or blur/focus,
but I expect too many sites would break.

What do you all think? I care more about meeting the use-case listed above
than matching the spec. If we can meet the above use-case differently, I
expect we could get the spec modified.

Ojan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20100721/1c2f9575/attachment.html>


More information about the webkit-dev mailing list