Monday, October 12, 2009

Web developers, please stop stealing focus.

Some sites use a very simple bit of JavaScript to put the focus in a specific form element once the page is done loading. Google does this, as was pointed out by Patrick Altoft in document.f.q.focus(); The Billion Dollar Line of JavaScript. When your browser loads the Google home page, this snippet of code automatically places your keyboard's focus in the main search box.

This makes a lot of sense for Google. There's really only one form element on Google's home page. That's where the focus should go. There's really no harm in placing the focus there, and as Patrick pointed out, it's a good source of revenue for Google. I believe that is what's termed a win-win.

You know where this doesn't make sense? Any page with a password field. When I load Twitter's (for just one example) main page, I'm greeted by a log in screen. The problem is that I have plenty of time to type in my username and tab to the password field before the page finishes loading and Twitter's version of the "Billion-dollar line of JavaScript" switches my focus back to the username field. This has caused me to type my password in plain text into the username field on several occasions. I do not care for this.

Granted, this is only a mild irritant, and now that I know Twitter is stealing my focus I can just change my behavior to compensate. The point is that I shouldn't have to. It would be a lot simpler to change the behavior of Twitter's login page than it would be to change the behavior of millions of users.

Possible solutions

The simplest (and I think the best) solution is for everyone to simply stop adjusting page focus using JavaScript. Unless your form has exactly one text field (and I can only think of a few of these), you really shouldn't assume you know where focus should go. Let the user handle it.

Another possibility is to check what field currently has focus before you change it. If the user is already using your page, just let it go. If none of your form elements currently has focus, go ahead and suggest a starting point by focusing on the first form element.

Finally, as a compromise between the two solutions above (and this is my recommended solution), just don't steal focus on any page that contains a password field. If there's a possibility of revealing the user's login credentials to passers-by, then just don't take the risk.

9 comments:

THK said...

I know very few about JavaScript and didn't know why I've been annoyed during my password keying on some websites. Now, after reading your article, I finally know that's due to the unnecessary JavaScript.

Yes, just let users to handle what they are using. Some ``automative'' functions are not so useful as the designers think of.

Nick said...

I've had this happen on pages where there is just one text box and no password box... where the search box gets focused, and I try to use space to page down and nothing happens (or I scroll back up to the search box is on the screen).

Dave said...

Another option would be to check the text field you're going to focus to. If it contains anything other than default text, don't focus to it. The user is clearly done with it.

Bill the Lizard said...

Dave,
I guess I've been using Stack Overflow too much, since I instinctively reached to upvote your comment. Good suggestion.

Niyaz PK said...

I had similar thoughts on this: http://www.diovo.com/2009/04/javascript-better-way-to-set-focus-in-page-load/

The best way to deal with this is to do a check like Dave suggested.

Sam152 said...

Dude, I have the exact same problem. And it really isn't that hard to simply check where the user is focused and take no action if they are one step ahead of the page load.

Good post.

Anonymous said...

I have this problem as well. What's the best way to stop sites from stealing focus?

Bill the Lizard said...

Colin Li,
If you really want to prevent sites from stealing focus you can disable JavaScript in your browser. In FireFox you can go to Tools > Options > Content and uncheck the "Enable JavaScript" option.

Unfortunately JavaScript is in extremely widespread use for a lot of other applications on the web, so leaving it disabled won't be an option for most people.

scunliffe said...

Hi fellow Stacker,

There is an easy way to solve this that I've implemented 100's of times without fail.

right after the username field (or whatever field you want to focus) immediately focus that field before rendering anything else.

e.g.
[input name="username"]
[script]
(
var fIdx = document.forms.length -1;
var iIdx = document.forms[fIdx].length -1;
document.forms[fIdx].elements[iIdx].focus();
)();
[/script]
[input name="password"]

(swap square for angle brackets etc)

You can tidy up the JavaScript or put in in a named function etc. but the logic is clean.

As soon as the field you want to focus renders, focus the field.

The user can then type in the username, password or whatever other fields they want in any order without losing the focus... and even submit the form before the page finishes loading depending on the page ;-)