• 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,代码示例如下:

    1
    2
    3
    4
    <div class="parent">
        <input type="text" />
    </div>
    <div class="log"></div>

    javascript代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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 代码

    1
    2
    3
    4
    <form name="form">
      <input type="text" name="name" value="Your name">
      <input type="text" name="surname" value="Your surname">
    </form>

    javascript 代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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>
  • 相关阅读:
    -lpopt is not found while cross compiling for aarch64
    设置进程的cpu亲和性
    在ARM64位开发板上兼容ARM32位的可执行程序
    ARM开发板上查看动态库或者可执行程序的依赖关系
    交叉编译tmux
    使用PSCI机制的SMP启动分析
    将qemu使用的设备树dump出来
    故障review的一些总结
    理解Compressed Sparse Column Format (CSC)
    统计分析工程的依赖项
  • 原文地址:https://www.cnblogs.com/weixuechao/p/6428771.html
Copyright © 2020-2023  润新知