说说focus /focusin /focusout /blur 事件

事件触发时间

focus:当focusable元素得到焦点时,不支持冒泡;
focusin:和focus同样,只是此事件支持冒泡;
blur:当focusable元素失去焦点时,不支持冒泡;
focusout:和blur同样,只是此事件支持冒泡;javascript

之前一直觉得全部事件都是支持冒泡的,都是能够cancel的,查阅了[MDN上相关资料](https://developer.mozilla.org/en-US/docs/Web/Events)后,才发现有些事件支持冒泡,有些事件并不支持冒泡;有些事件有默认行为(这类事件能够cancel),有些事件压根儿就没有默认行为(这类事件就不能 cancel )。从 MDN 上能够清楚的看到 focusblur这2种事件不支持冒泡,支持冒泡的事件是focusinfocusouthtml

事件触发顺序

对于同时支持这4个事件的浏览器,事件执行顺序为focusin > focus > focusout > blur,代码示例以下:java

html代码chrome

<div class="parent">
    <input type="text" />
</div>
<div class="log"></div>

javascript代码浏览器

function log(str){
  $('.log').append($('<div/>').text(str));
}

$('.parent')
    .focusin(function(){log('div focusin');})
    .focusout(function(){log('div focusout');})
    .focus(function(){log('div focus');})
    .blur(function(){log('div blur');});
$('input')
    .focusin(function(){log('input focusin');})
    .focusout(function(){log('input focusout');})
    .focus(function(){log('input focus');})
    .blur(function(){log('input blur');});

执行结果app

clipboard.png

从执行结果能够看到4个事件的执行顺序,同时也能够看到 focus/blur是不支持冒泡的,因此.parent 元素绑定的focusblur事件回调并无触发。this

focusin 与 focusout的浏览器支持

几乎全部的浏览器都支持focusblur事件,但对于focusinfocusout 就不是这样理想了。Firefox中不支持focusinfocusout事件;chrome和safari中只有经过addEventListener方式绑定事件才能正常使用,其余方式绑定都不行;spa

面对这样的浏览器支持彷佛很头痛,庆幸的是jQuery对focusinfocusout作了兼容,使用$.focusin$.focusout实现事件绑定,在全部浏览器中都支持;代理

focusblur如何实现事件代理

事件代理简单来讲就是将子元素事件绑定在祖先元素上,之因此可以这样作,得益于标准事件模型的捕获和冒泡。咱们知道在标准事件模型中,一个事件的触发会经历三个阶段:捕获阶段+目标阶段+冒泡阶段,有了捕获和冒泡才能实现事件代理。由前面介绍可知,focusblur不支持冒泡,但其支持捕获,但 IE 中事件模型没有捕获只有冒泡,因此在非IE浏览器中能够经过在捕获阶段进行事件绑定实现事件代理。那么针对IE浏览器怎么实现呢?经过支持冒泡的是focusinfocusout实现就能够了。代码示例以下:code

html 代码

<form name="form">
  <input type="text" name="name" value="Your name">
  <input type="text" name="surname" value="Your surname">
</form>

javascript 代码

function addColor(){
  this.style.background="red";
}
var form = document.forms['form'];
if (form.addEventListener) { // 非 IE 浏览器
  form.addEventListener('focus', addColor, true);
}else{  // IE
  form.onfocusin = addColor
}

哪些元素是focusable的

在本文的第一小节提到了一个 focusable 元素的概念,我以为有必要在这里解释一下什么是focusable 元素。
默认状况下,只有部分html元素能得到鼠标焦点如input,很大一部分html元素是不能得到鼠标焦点的如div,这些可以得到鼠标焦点的元素就是focusable 元素。要想一个元素得到焦点,能够经过三种方式:

  • 鼠标点击

  • tab 键

  • 调用focus()方法

那么默认状况下,哪些元素是focusable 元素

  1. window:当页面窗口从隐藏变成前置可见时,focus 事件就会触发

  2. 表单元素(form controllers):input/option/textarea/button

  3. 连接元素(links):a标签、area标签(必需要带 href 属性,包括 href 属性为空)

  4. 设置了 tabindex 属性(tabindex 值非-1)的元素

  5. 设置了contenteditable = "true"属性的元素

tabindex属性

默认状况下就能 focusable 的元素太少,若是想让一个 div 元素成为 focusable 的元素怎么作呢?很简单,设置 tabindex 属性便可!
tabindex 有2个做用:

  1. 使一个元素变成 focusable
    只要在元素上设置了 tabindex 属性,无论此属性的值设为多少,此元素都将变成focusable元素。

  2. 定义屡次按下 TAB 键时得到焦点的元素顺序
    tabindex 属性的值能够正数、0、负数,当屡次按下TAB键,首先是tabindex为正数的元素得到焦点,顺序是:tabindex=一、tabindex=二、tabindex=三、tabindex=...,最后是tabindex=0的元素得到焦点。注意:tabindex为负数的元素不能经过 TAB 键得到焦点,只能经过鼠标点击或者调用focus()方法才能得到焦点。示例代码以下:

<ul>
<li tabindex="1" onfocus="showFocus(this)">One</li>
<li tabindex="0" onfocus="showFocus(this)">Zero</li>
<li tabindex="2" onfocus="showFocus(this)">Two</li>
<li tabindex="-1" onfocus="showFocus(this)">Minus one</li>
<li tabindex="-2" onfocus="showFocus(this)">Minus two</li>
</ul>
相关文章
相关标签/搜索