Sent to you by Hudong via Google Reader:
I've been working on some bugs in the Calendar extender from the ASP.NET AJAX Control Toolkit and have been resolving some of the focus/blur events. I've been trying to make the calendar work consistently across all of the browsers and found some frustrating differences in event firing order between the browsers.
Here are a list of some of the DOM events supported by the various browsers I tested:
Table 1 - DOM Events by Browser
Event | DOM Level | IE | FF | OP | SF |
DOMActivate | Level 2 | * | |||
activate | 2 | * | |||
DOMFocusIn | Level 2 | 1 | 1 | ||
focusin | 2 | * | |||
focus | Level 0 | * | 1 | 1 | 1 |
DOMDeactivate | Level 2 | ||||
deactivate | 2 | * | |||
DOMFocusOut | Level 2 | 1 | 1 | ||
focusout | 2 | * | |||
blur | Level 0 | * | 1 | 1 | 1 |
mousedown | Level 0 | * | * | * | * |
mouseup | Level 0 | * | * | * | * |
click | Level 0 | * | * | * | * |
IE: Internet Explorer 7.0
FF: Firefox 2.0.0.6
OP: Opera 9.23
SF: Safari 3.03 Beta (Windows)
*: Implemented on any element
1: Implemented only on specific elements
2: IE-only implementation
Internet Explorer uses activate/focusin/focusout instead of DOMActivate/DOMFocusIn/DOMFocusOut for events. Interestingly only IE and Safari support DOMActivate/activate on any element. Another thing I saw was that IE is the only browser which fires focus/blur events for any element. Other browsers can support the focus/blur events on any element that has a tab index however.
The next version of Calendar needs to support the following activation scenarios depending on whether it is also associated with a button:
- No Button
- Show Popup when textbox receives focus
- Show Popup when textbox is clicked
- Hide Popup when textbox loses focus
- Hide Popup when textbox receives ESC keypress
- Hide Popup when a date is selected
- Button
- Show Popup when the button is clicked
- Hide Popup when the button loses focus
- Hide Popup when the button receives ESC keypress
- Hide Popup when a date is selected
The issue is that when the textbox or button loses focus the popup should hide unless the focus is being directed at the popup itself. The problem is that only IE recognizes a focus event on the popup's DIV tag when the popup is not part of the tab order (and we don't want the popup in the tab order). I was curious the order of DOM events fired in each browser so I wrote a small test page and stepped through for each. The results are as follows:
Table 2 - DOM Event Order by browser
IE | FF | OP | SF |
|
|
|
|
Immediately a few things become obvious. First, I obviously cannot rely on focus/blur on the other browsers. IE would allow me to capture focusin on the DIV before the blur fires on the INPUT but that's just IE. Second, on all browsers except Opera the mousedown event of the DIV fires before the blur event of the INPUT. There's no clean sequential way to handle the focus transition in all browsers.
In the current version of Calendar we're making use of a "threading" class I created for the toolkit called DeferredOperation. DeferredOperation wraps a delegate and executes it asynchronously using setTimout. It has some built-in synchronization semantics and was used to handle the focus changes while the popup DIV was part of the tab order (which again, we don't really want). This introduces a subtle delay between activation requests and is problematic on Safari (we had to wait a full second before processing the deferred operation to let safari to catch up).
What I've opted for now is to do the best I can in three out of four of the browsers. I track mousedown/mouseup using a flag and in Internet Explorer, Firefox, and Safari and monitor the flag in the blur event of the textbox. To handle the Opera inconsistency I again use a DeferredOperation to asynchronously handle the blur event which fixes the issue in that browser.
The final issue I discovered was that in all browsers, clicking on the popup causes the textbox (or button) to lose focus which again causes problems with the tab order. On the new Calendar I reset the focus to the textbox (or button) on mouseup on the popup.
Hopefully these changes should make the next toolkit release so keep an eye out for the next update.
Things you can do from here:
- on MSDN Blogs
- Subscribe to MSDN Blogs using Google Reader
- Get started using Google Reader to easily keep up with all your favorite sites
没有评论:
发表评论