说说focus /focusin /focusout /blur 事件

事件触发时间

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

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

事件触发顺序

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

<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‘);});

执行结果

从执行结果可以看到4个事件的执行顺序,同时也可以看到 focus/blur是不支持冒泡的,所以.parent 元素绑定的focusblur事件回调并没有触发。

focusin 与 focusout的浏览器支持

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

面对这样的浏览器支持似乎很头痛,庆幸的是jQuery对focusinfocusout做了兼容,使用$.focusin$.focusout实现事件绑定,在所有浏览器中都支持;

focusblur如何实现事件代理

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

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=1、tabindex=2、tabindex=3、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>
时间: 2024-10-13 06:19:24

说说focus /focusin /focusout /blur 事件的相关文章

focus、blur事件的事件委托处理(兼容各个流浏览器)

今天工作中遇到个问题,问题是这样的,一个form表单中有比较多的input标签,因为form中的input标签中的值都需要前端做客户端校验,由于本人比较懒而且特不喜欢用循环给 每个input元素添加blur事件处理,感觉这样有损专业前端形象!想过用事件委托,然而focus.blur事件利用冒泡机制搞事件委托行不通啊,父级元素不支持focus.blur咋办???? 由此引发了对此问题的思考,人生就是这样,总觉得自己NB的不行,感觉自己什么都会,然而你在没遇到boss的时候打着小怪一直都会觉得自己天

bobojQuery focus和blur事件的应用详解

一.需求原因在填写表单时需要实现如下效果二.具体实现 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type"content="text/htm

jquery文本框的focus和blur事件

jquery文本框的focus和blur事件 focus事件在元素获取焦点时触发,如点击文本框时,触发该事件:而blur事件则在元素丢失焦点时触发,如点击除文本框的任何元素,都会触发该事件 代码如下 <body> <h3>表单中文本框的focus和blur事件</h3> <input id="txtest" type="text" value="" /> <div></div>

详说jQuery的focus()、blur()事件

what focus():当元素获得焦点时,发生 focus 事件. blur():当元素失去焦点时发生 blur 事件. 小例子 HTML文件 Enter your name: <input type="text" /> javascript文件: $(document).ready(function(){ $("input").focus(function(){ $("input").css("background-co

div无法触发blur事件解决的方法

默认情况下div无法获取焦点,无法触发focus与blur事件,推測span,a等标签也无法触发焦点事件(input:button.及button标签能够触发) 怎样使div触发blur事件:能够给div加上tabindex属性 在线演示:http://sandbox.runjs.cn/show/e0bvfcag 源代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U

【原】相煎何太急——input的blur事件与button的click事件

先来一段引子,最近在写手机h5页面,主要是一些登陆注册方面的,最绕不开的就是表单元素. 我想实现的是:在输入框后边有一个删除图标,当输入东西的时候触发事件,显示删除图标,点击该图标会删除之前输入的内容,离开输入框,该图标消失. <div class="wrapper"> <div class="count"> <label for="person">手机号</label> <input id=

div无法触发blur事件解决办法

默认情况下div无法获取焦点,无法触发focus与blur事件,猜测span,a等标签也无法触发焦点事件(input:button,及button标签可以触发) 如何使div触发blur事件:可以给div加上tabindex属性 在线演示:http://sandbox.runjs.cn/show/e0bvfcag 源码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT

react 中的blur事件

我们知道,想要手动触发blur事件时候,可以使用:https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/blur Element.blur() 然而在react中,当你想手动触发一个input的blur事件时,你会得到一个错误:blur is not a function 在react中,当我们要操纵dom时候,我们一般会使用ref,比如focus事件: this.ref.current.focus() // 这个会运行的很好

jquery点击click事件和blur事件冲突如何解决

最近做了一个查询小功能,input输入框输入文字后,自动列出几条查询结果,可以键盘上下键或鼠标进行查询结果选择,并且点击输入框其他地方要隐藏这个列出的结果. 但比较头疼的是input上添加blur事件和查询提示结果click事件发生冲突,点击查询结果时,会首先触发input的blur事件,导致将查询提示结果隐藏选择不了, 解决办法: 给blur失去焦点事件添加延迟事件,让blur事件在click事件后执行. $(".query_tools").blur(function(event){