2009.11 29

改善登陆界面的用户体验: 自动聚焦表单

在登陆界面中,通常,最重要的部分为登陆的Form表。一个非常棒的提升体验的做法是,在载入页面时自动聚焦到第一个提供用户输入的表单框,让用户不用再多一个点击,就可以输入。这被很多网站采用。记得这在10个改善UI设计的技术(2)这篇文章中也有提到过,这也被很多网站采用,比如维基百科就是这样:

auto focus

当然,自动聚焦不仅仅适合在登陆界面,而适合在任何需要的界面。比如WordPress登陆后台的界面和支付宝的登陆界面,都采用了自动聚焦的方法。

auto focus

而具体应该是怎样实现的呢?假设我们的表单如下:

<form id="signin" method="post" name="signin" action="http://www.happinesz.cn">
 <input value="hidefor" type="hidden" name="hide" />
 <input id="usr" name="usr" />
 <input id="pwd" type="password" name="pwd" />
 <input id="smbt" value="submit" type="button" name="smbt" />
</form>

我们要让焦点落在id="usr"input上,用 Javascript 的方法,我们可以这样做:

  document.forms["signin"].elements["usr"].focus();

这里是当我们明确知道要在那个表单上添加 focus 的时候可以用的方法。这里,elements也可以用方括号的方法来获取input表单,比如.elements[0]即为第一个input表单。当我们要聚焦的 input前面有type="hidden"的隐藏input,由于隐藏的input是不支持.focus的,一旦应用其上,就会出现Javascript错误,要避免这样的的错误。我们可以搜索第一个表单中,第一个非隐藏的 input,并给加上.focus:(除非你是想封装起来,自动判断,不然,最好不要用这个方法,多浪费资源啊,又if又for的)

window.onload = function(){
 if(document.forms.length>0){
  for(i=0;i<document.forms[0].elements.length; i++){
   var oInput = document.forms[0].elements[i];
   if(oInput.type!="hidden"){
    oInput.focus();
    return;
   }
  }
 }
}

到这里,很多网站都只做到这里,比如我前面提到的Wordpress的登陆界面和支付宝的登陆界面。他们的目标的相同的,提升用户体验。我的目标也这样。但是,这有时候,这并不一定提升了用户体验。为什么呢?

想想,你是不是也曾出现过这样的状况:当时,你的网速并不快,你进入www.alipay.com的时候,还没有自动聚集,因为JS还没加载。但,你已经输入用户名了,并且已经在输入密码。好,打住。我们来讲个故事:很久很久以前,有个叫sofish,他当时挂着迅雷在下载XXX东西,急着想要用支付宝,当时页面还没有加载完,输入用户名后,正准备输入密码(习惯性地用键盘上的TAB键来切换到密码框),然后,抬头,当时,密码出现在输入用户名的框上,并且,旁边有一同学正在那里看着。

你看,你看,难道,这样的自动聚焦提升了用户的所谓的体验么? 这里,就往往相反,可能导致用户要重新改密码(比如那个当时RP比较低下的叫sofish的家伙)。

有什么方法可以解决么?当然!我们把上面的代码改装如下:

window.onload = function(){
 if(document.forms.length>0){
  for(i=0;i<document.forms[0].elements.length; i++){
   var oInput = document.forms[0].elements[i];
   if(oInput.type!="hidden" && oInput.value==""){
    oInput.focus();
    return;
   }
  }
 }
}

但是,这样一来,这个聚集就会自动跳到下一个非隐藏的input中,如果我正在输入,那不是很不爽? 嗯,当然不爽,所以,我们再折腾一下,做点小改正:

window.onload = function(){
 if(document.forms.length>0){
  for(i=0;i<document.forms[0].elements.length; i++){
   var oInput = document.forms[0].elements[i];
   if(oInput.type!="hidden" && oInput.value.length>0){
     oInput.blur();
     return;
   }else if(oInput.type!="hidden"){
    oInput.focus();return
    }
  }
 }
}

由于在oInput.type!="hidden"中有一种情况,即当用户已经输入的时候,他会自动聚集到下一个,这样,也有问题,所以,我们让如果已经有输入的情况下,去掉所有input的焦点,而 else if中才让没有输入的用户自动对焦到第一个。(当然,如果有人习惯先输入密码,再输入用户名,那就再另想办法吧)。

其实,这样,有时候好用,但有时候相当于根本不去自动聚焦。不过,对于保护用户的输入(特别是密码)来说,我想,用改进的方法,会比无改进的自动聚焦和根本不自动聚集来得好。当然,我相信,会有更好的方法。请不吝赐教。其他的就让我这个爱折腾的JS编程学院新生慢慢发现吧。

29

  1. 2009.11.29 8:18 pm
    xiao3(visit): [回复]

    友情沙发?

  2. 2009.11.29 8:38 pm
    辐射鱼(visit): [回复]

    只抢到地板,唉

  3. 2009.11.29 8:40 pm
    bolo(visit): [回复]

    从js代码可以看出考虑得非常周到啊

  4. 2009.11.29 10:22 pm
    网页设计手册(visit): [回复]

    虽然很简单,但很实用,写的也很精彩

  5. 2009.11.30 2:20 am
    welee(visit): [回复]

    写代码就是要考虑到足够多会发生的情况,照顾得越全面,代码的bug也越少。

  6. 2009.11.30 9:19 am
    Leeiio(visit): [回复]

    呃,被我发现一处错误,判断空值怎么变成 oInput.value==0了…漏写了length吧,oInput.value.length ==0…,话说干嘛不用==”"

  7. 2009.11.30 10:47 am
    leehow(visit): [回复]

    明天十二月了。

  8. 2009.11.30 12:05 pm
    sofish(visit): [回复]

    @Leeiio: 嗯,真细心,被你发现了。似乎可以不用多一个.length,thanks!

    @leehow: 嗯。你好久没更新了…

  9. 2009.11.30 4:12 pm
    underone(visit): [回复]

    看不懂的飘过…

  10. 2009.11.30 7:02 pm
    ZH CEXO(visit): [回复]

    看来你真的在一心研究js,俺泪目了……

  11. 2009.12.01 2:30 pm
    aunsen(visit): [回复]

    JS=奸商!

  12. 2009.12.01 3:04 pm
    左岸读书(visit): [回复]

    这种良好的用户体验能给人留下美好的感觉!

  13. 2009.12.01 3:07 pm
    crossyou(visit): [回复]

    好热闹啊,来学习下。

  14. 2009.12.02 9:25 am
    mars(visit): [回复]

    细节决定成败,相当受用

  15. 2009.12.02 9:29 am
    mars(visit): [回复]

    另外提一点,主题上博友评论的名字是否用红色值得考究一下

  16. 2009.12.02 1:25 pm
    Hobo(visit): [回复]

    也可以用jQuery来实现呵呵

  17. 2009.12.02 6:21 pm
    Mars(visit): [回复]

    学习了。

  18. 2009.12.02 6:29 pm
    sofish(visit): [回复]

    @mars: 嗯,感觉只是为了衬中国风的配色。

  19. 2009.12.05 9:41 pm
    吖Bee(visit): [回复]

    很细节的体现

  20. 2009.12.06 11:53 am
    Duia(visit): [回复]

    我也是看不懂的,算是边看边学习的那种。。。

  21. 2009.12.23 6:16 pm
    蓝霁a千(visit): [回复]

    很好的想法,已经很不错啦~~继续努力哈!!

  22. 2009.12.24 2:25 pm
    ixwebhosting中文(visit): [回复]

    用wordpress那么久,从来没有考虑过这些。。

  23. 2010.01.21 9:30 pm
    is下载(visit): [回复]

    谢谢,很有用

  24. 2010.01.27 2:56 pm
    YY下载(visit): [回复]

    不错,看起来好多了

  25. 2010.05.04 3:42 pm
    lik(visit): [回复]

    用 document.activeElement.tagName 判断下当前焦点是否在 INPUT 标签里就可以了

    window.onload = function(){
    if(document.activeElement.tagName!=’INPUT’){
    if($(“#username”).val()){
    $(“#password”).focus();
    } else {
    $(“#username”).focus();
    }
    }
    }

    和 INPUT 一样可以加上 TEXTAREA。

    如果再考虑周全,还要考虑在页面加载时用户用鼠标选中了一部分内容(比如想复制文字),这个也得判断下。

  26. 2010.05.06 6:23 pm
    he(visit): [回复]

    再来拜访!

  27. 2010.05.22 8:43 am
    wantfee(visit): [回复]

    完全不懂JS,目前只能Ctrl+C和Ctrl+V着用,慢慢学习。

  28. 2010.06.10 9:29 am
    有限电视(visit): [回复]

    很实用,很精彩

  29. 2010.06.23 11:39 am
    theday(visit): [回复]

    这个很有用.. 不错. 收下了.

Additional comments powered by BackType