.focus() with a delay

2,067 views
Skip to first unread message

Scott González

unread,
Oct 26, 2008, 7:30:01 PM10/26/08
to jQuery UI Development
Dialog currently uses a delayed call to DOMElement.focus() to control tabbing through the dialog:

setTimeout(function() {
    el.focus();
}, 1);

It has been pointed out that this should always be done when setting focus for accessibility reasons.  We should add a method in ui.core.js that does this for us.  I'd like to just overwrite $.fn.focus() to do this, but I really don't think it's a good idea to switch a synchronous function to an asynchronous function.  Does anyone have any ideas for a different name?  .setFocus(), .accessibleFocus(), .delayedFocus()?

Richard D. Worth

unread,
Oct 27, 2008, 7:41:37 AM10/27/08
to jquery...@googlegroups.com
I like setFocus.

- Richard

Scott González

unread,
Jan 21, 2009, 9:38:20 AM1/21/09
to jQuery UI Development
Should this method force the element to be focusable?  This would
happen by checking if the element has a tabindex and if it doesn't, it
would set it to -1 before setting focus.  Or, should it just try to
set focus and fail silently?

Eduardo Lundgren

unread,
Jan 21, 2009, 12:58:03 PM1/21/09
to jquery...@googlegroups.com
If we keep the name .delayedFocus() we have to give the possibility to specify the delay in ms to be compatible with the name.

If we use setFocus() and receive a parameter like:
    - .setFocus(1) - use the asynchronous focus with 1ms of delaying.
    - .setFocus() - use the synchronous focus, without setTimeout.

What about .asyncFocus() with no parameters ? this name means that I want to set the focus asap (0 or 1 ms) and asynchronously.
--
Eduardo Lundgren
Software Engineer
Liferay, Inc.
Enterprise. Open Source. For Life.

Scott González

unread,
Jan 21, 2009, 5:30:39 PM1/21/09
to jquery...@googlegroups.com
Currently the idea is to use setFocus for the name (unanimous so far - it's what we've been using in the experimental branch).  The current implementation does accept a delay like you've suggested, but does not allow for not passing a value and doing it synchronously.  If you want a synchronous focus, use .focus() - .setFocus() will default to a 1ms delay.

You can see the current implementation at http://jquery-ui.googlecode.com/svn/branches/experimental/tabbable/ui.core.js

Really the only question to answer is whether this should force the element to be focusable or whether it should be up to the developer to ensure the element is focusable before trying to set focus.

Wichert Akkerman

unread,
Jan 22, 2009, 2:46:02 AM1/22/09
to jquery...@googlegroups.com
As newcomer here I would like to chime in :)

The naming sounds confusing to me, and it does not follow the pattern set by other jQuery functions. None of the jQuery core (or UI methods I've encountered so far) methods use "set" in their name but base their name solely on their task or the widget they are managing. In addition the naming is very non-intuitive. If I am reading code and I see calls to focus() and setFocus() mixed it would just confuse me.

I suspect the best approach to keep the API clean and intuitive is to fold this into the core focus() method and expose it via an option. Something like $(this).focus({delay: 500, async : true}); If that I would go for Eduardo's suggestion to rename it to asyncFocus (or delayedFocus?): that immediately reveals the purpose of the method in its name.

Regards,
Wichert.

alexander farkas

unread,
Jan 22, 2009, 5:19:19 AM1/22/09
to jQuery UI Development
Hi everyone,
1. Method-Naming
To proxy and overload the focus-method is a nice idea (The first
parameter should be a number ).

2. Forcing focusability
If you only check the tabindex and not the visibility of the element
and its ancestors, it would be a nice feature, that doesn´t hurt
anyone.

Regards,
Alex

Paul Bakaus

unread,
Jan 22, 2009, 5:23:28 AM1/22/09
to jquery...@googlegroups.com
On Thu, Jan 22, 2009 at 8:46 AM, Wichert Akkerman <wic...@wiggy.net> wrote:
As newcomer here I would like to chime in :)

Thanks for chiming in Wichert. Any help is appreciated.
 


The naming sounds confusing to me, and it does not follow the pattern set by other jQuery functions. None of the jQuery core (or UI methods I've encountered so far) methods use "set" in their name but base their name solely on their task or the widget they are managing. In addition the naming is very non-intuitive. If I am reading code and I see calls to focus() and setFocus() mixed it would just confuse me.

I agree it's not very semantical. If we have to choose a another option name I'd stick to delatedFocus because it directly describes the action.
 


I suspect the best approach to keep the API clean and intuitive is to fold this into the core focus() method and expose it via an option. Something like $(this).focus({delay: 500, async : true}); If that I would go for Eduardo's suggestion to rename it to asyncFocus (or delayedFocus?): that immediately reveals the purpose of the method in its name.

I like that - it's fairly easy in the case of focus because it doesn't have any arguments by default, and it shouldn't slow down the original focus() method significantly.
 


Regards,
Wichert.



On 1/21/09 11:30 PM, Scott González wrote:
Currently the idea is to use setFocus for the name (unanimous so far - it's what we've been using in the experimental branch).  The current implementation does accept a delay like you've suggested, but does not allow for not passing a value and doing it synchronously.  If you want a synchronous focus, use .focus() - .setFocus() will default to a 1ms delay.

You can see the current implementation at http://jquery-ui.googlecode.com/svn/branches/experimental/tabbable/ui.core.js

Really the only question to answer is whether this should force the element to be focusable or whether it should be up to the developer to ensure the element is focusable before trying to set focus.


On Wed, Jan 21, 2009 at 12:58 PM, Eduardo Lundgren <eduardo...@gmail.com> wrote:
If we keep the name .delayedFocus() we have to give the possibility to specify the delay in ms to be compatible with the name.

If we use setFocus() and receive a parameter like:
    - .setFocus(1) - use the asynchronous focus with 1ms of delaying.
    - .setFocus() - use the synchronous focus, without setTimeout.

What about .asyncFocus() with no parameters ? this name means that I want to set the focus asap (0 or 1 ms) and asynchronously.




On Wed, Jan 21, 2009 at 6:38 AM, Scott González <scott.g...@gmail.com> wrote:
Should this method force the element to be focusable?  This would
happen by checking if the element has a tabindex and if it doesn't, it
would set it to -1 before setting focus.  Or, should it just try to
set focus and fail silently?





--
Eduardo Lundgren
Software Engineer
Liferay, Inc.
Enterprise. Open Source. For Life.












--
Paul Bakaus
UI Architect
--
http://paulbakaus.com
http://www.linkedin.com/in/paulbakaus

Scott González

unread,
Jan 22, 2009, 11:12:34 AM1/22/09
to jquery...@googlegroups.com
How about overriding $.fn.focus so it behaves as follows:

- no parameters = trigger focus immediately (current behavior)
- function as parameter = bind handler to focus event (current behavior)
- number as parameter = trigger focus asynchronously with a <number> ms delay (new behavior)

Paul Bakaus

unread,
Jan 23, 2009, 3:46:52 AM1/23/09
to jquery...@googlegroups.com
On Thu, Jan 22, 2009 at 5:12 PM, Scott González <scott.g...@gmail.com> wrote:
How about overriding $.fn.focus so it behaves as follows:

- no parameters = trigger focus immediately (current behavior)
- function as parameter = bind handler to focus event (current behavior)
- number as parameter = trigger focus asynchronously with a <number> ms delay (new behavior)

+1
 



On Thu, Jan 22, 2009 at 2:46 AM, Wichert Akkerman <wic...@wiggy.net> wrote:
As newcomer here I would like to chime in :)

The naming sounds confusing to me, and it does not follow the pattern set by other jQuery functions. None of the jQuery core (or UI methods I've encountered so far) methods use "set" in their name but base their name solely on their task or the widget they are managing. In addition the naming is very non-intuitive. If I am reading code and I see calls to focus() and setFocus() mixed it would just confuse me.

I suspect the best approach to keep the API clean and intuitive is to fold this into the core focus() method and expose it via an option. Something like $(this).focus({delay: 500, async : true}); If that I would go for Eduardo's suggestion to rename it to asyncFocus (or delayedFocus?): that immediately reveals the purpose of the method in its name.



Wichert Akkerman

unread,
Jan 23, 2009, 3:51:10 AM1/23/09
to jquery...@googlegroups.com
On 1/23/09 9:46 AM, Paul Bakaus wrote:


On Thu, Jan 22, 2009 at 5:12 PM, Scott González <scott.g...@gmail.com> wrote:
How about overriding $.fn.focus so it behaves as follows:

- no parameters = trigger focus immediately (current behavior)
- function as parameter = bind handler to focus event (current behavior)
- number as parameter = trigger focus asynchronously with a <number> ms delay (new behavior)

+1

To keep things consistent both function and number should be supported as well.

Regards,
Wichert.

Richard D. Worth

unread,
Jan 23, 2009, 5:16:29 AM1/23/09
to jquery...@googlegroups.com
On Thu, Jan 22, 2009 at 11:12 AM, Scott González <scott.g...@gmail.com> wrote:
How about overriding $.fn.focus so it behaves as follows:

- no parameters = trigger focus immediately (current behavior)
- function as parameter = bind handler to focus event (current behavior)
- number as parameter = trigger focus asynchronously with a <number> ms delay (new behavior)


+1

- Richard

Scott González

unread,
Jan 23, 2009, 7:57:25 AM1/23/09
to jquery...@googlegroups.com
On Fri, Jan 23, 2009 at 3:51 AM, Wichert Akkerman <wic...@wiggy.net> wrote:
To keep things consistent both function and number should be supported as well.

I'm not sure which situation you're referring to:

.focus(1, fn) or .focus(fn, 1)

If it's the former, I agree, and the function should be a callback.

Wichert Akkerman

unread,
Jan 23, 2009, 9:54:26 AM1/23/09
to jquery...@googlegroups.com

The former indeed. Similar to other jQuery methods the possible calling
options should imho be:

.focus()
.focus(delay)
.focus(delay, callback)

all of which should return the jQuery instance so they chain properly.

.focus(callback) does not add anything useful that I can think of, and I
can find no other jQuery with that calling convention.

The second

--
Wichert Akkerman <wic...@wiggy.net> It is simple to make things.
http://www.wiggy.net/ It is hard to make things simple.

Scott González

unread,
Jan 23, 2009, 10:24:57 AM1/23/09
to jquery...@googlegroups.com
On Fri, Jan 23, 2009 at 9:54 AM, Wichert Akkerman <wic...@wiggy.net> wrote:
.focus(callback) does not add anything useful that I can think of, and I
can find no other jQuery with that calling convention.

It's actually .focus(eventHandler), which is a shortcut for .bind('focus', eventHandler).

Eduardo Lundgren

unread,
Jan 23, 2009, 12:39:32 PM1/23/09
to jquery...@googlegroups.com
+1 for overloading .focus following the idea Scott said

Scott González

unread,
Apr 18, 2009, 9:11:56 AM4/18/09
to jQuery UI Development
This has been implemented in r2473.
Reply all
Reply to author
Forward
0 new messages