首页
div焦点事件详解

起因

最近做一个需求,需要鼠标悬浮在div上按Enter键触发事件,但是直接用onkeydown()触发不了事件,研究了一下,发现只有获取焦点的元素才能触发键盘事件。

Keyboard events are commonly directed at the element that has the focus.
大概就是说键盘按键事件一般指向能获取焦点的元素,就是不能获取焦点的元素就不能触发键盘按键事件了。

focus和tabindex

  • w3c关于onfocus,可以看到默认支持onfocus的有A,AREA,INPUT,SELECT,TEXTAREA和BUTTON
  • tabindex支持的有A, AREA, BUTTON, INPUT, OBJECT, SELECT, and TEXTAREA
  • 当元素通过指定(点击)或tab导航(Tabbing navigation)获得焦点,onfocus事件就会触发。
    该属性会使用在以下元素(就是说默认可以获取焦点的元素):A, AREA, LABEL, INPUT, SELECT, TEXTAREA, and BUTTON.

解决

所以解决办法就是让div得到焦点,msdn上说的很清楚。
只要元素的tabIndex属性设置成任何有效的整数那么该元素就能取得焦点。元素在取得焦点后就能触发onblur,onfocus,onkeydown, onkeypress和onkeyup事件。
不同tabIndex值在tab order(Tabbing navigation)中的情况:

  • tabIndex值是正数的对象根据递增的值顺序和代码中的位置顺序来被选择
  • tabIndex值是0的对象根据在代码中的位置顺序被选择
  • tabIndex值是负数的对象会被忽略

该怎么用

给div设置tabindex="-1",并且让鼠标移入的时候得到焦点,就可以触发onkeydown事件了,就是那么简单

<div tabindex="-1" onmousemove="this.focus();" onkeydown="alert(1);"></div>

不过div得到焦点后会有个虚线边框,要处理掉,加上一句css

div:focus{ outline: none; }

优化

上面介绍的只是基本的用法而已,按任何键都能触发事件,在一个项目中我们如何按不同的键响应不同的事件呢

$(document).keydown(function (e) {
    e = e || event;
    if (e.keyCode == 27){ // esc 键关闭所有打开的div
        //your code,一般关闭所有的弹出框
        $("body").focus();
        return false;
    }
    if (e.keyCode == 13) {    // enter键执行的事件
    var target = e.target ? e.target : e.srcElement;
    if (target.name != "aa"
        && target.id != "bb"
        && target.name != "cc"){
        return false;
    }
    if(target.name == "aa"){
        //your code
        return false;
    }
        return true;
    }
});