• 焦点相关事件兼容性问题


    概念:

     

    除了常见的 focus,blur 事件,DOM Level 3 事件模块 还定义了 focusin ,focusout 以及 DOMFocusIn ,DOMFocusOut 四个事件。

     

    规范:

     

    blur :

    在这个事件触发前,元素已经失去焦点,不冒泡,同步触发。target 指向当前失去焦点的元素。

     

    DOMFocusIn :

    在这个事件触发前,元素已经得到焦点,可冒泡,同步触发。target 指向当前得到焦点的元素。

     

    DOMFocusOut :

     

    在这个事件触发前,元素已经没有焦点,可冒泡,同步触发。target 指向当前失去焦点的元素。

     

    focus:

    在这个事件触发前,元素已经得到焦点,不冒泡,同步触发。target 指向当前得到焦点的元素。

     

    focusin :

    在当前元素获得焦点前以及相关元素失去焦点前触发,可冒泡,同步触发。target 指向当前将要获得焦点的元素,relatedTarget 指向失去焦点的元素

     

    focusout :

    在当前失去焦点前触发,可冒泡,同步触发。target 指向当前将要失去焦点的元素,relatedTarget 指向将要失去焦点的元素。

     

    触发顺序:

     

    假定有两个元素 1,2,先使得1 获得焦点再使得 2 获得焦点,那么事件的触发顺序以及触发源为

     

    focusin -> 元素 1

    元素 1 获得焦点

    focus -> 元素 1

    DOMFocusIn -> 元素 1

    focusout -> 元素 1

    focusin -> 元素 2

    元素 1 失去焦点

    blur -> 元素 1

    DOMFocusOut ->元素 1

    元素 2 获得焦点

    focus -> 元素 2

    DOMFocusIn -> 元素 2

     

    兼容性测试:

     

    测试代码:

    Html代码 复制代码 收藏代码
    1. <div tabindex="-1" id='a1'>  
    2.     area 1   
    3. </div>  
    4.   
    5. <div tabindex="-1" id='a2'>  
    6.     area 2   
    7. </div>  
    <div tabindex="-1" id='a1'>
        area 1
    </div>
    
    <div tabindex="-1" id='a2'>
        area 2
    </div>

    通过调用 focus()方法来进行焦点转移,(也可通过鼠标直接点击,但是就不能测试是否同步了)关于 div 的焦点可见这里

     

    具体 demo @ google code

     

    firefox 3.6.12

     

    没有 focusin,focusout,DOMFocusIn,DOMFocusOut事件,focus,blur为同步触发

     

    触发顺序为:

    Js代码 复制代码 收藏代码
    1. a1 focus target:a1   
    2. a1 focus relatedTarget:   
    3. keydown : 49   
    4. a1 blur target:a1   
    5. a1 blur relatedTarget:   
    6. a2 focus target:a2   
    7. a2 focus relatedTarget:   
    8. keydown : 50  
    a1 focus target:a1
    a1 focus relatedTarget:
    keydown : 49
    a1 blur target:a1
    a1 blur relatedTarget:
    a2 focus target:a2
    a2 focus relatedTarget:
    keydown : 50
     

    chrome 9.0

     

    全部事件都实现了,且都为同步触发,但是触发顺序和规范不一致,并且没有定义 relatedTarget 事件属性:

    Js代码 复制代码 收藏代码
    1. a1 focus target:a1   
    2. a1 focus relatedTarget:   
    3. a1 focusin target:a1   
    4. a1 focusin relatedTarget:   
    5. a1 DOMFocusIn target:a1   
    6. a1 DOMFocusIn relatedTarget:   
    7. keydown : 49   
    8. a1 blur target:a1   
    9. a1 blur relatedTarget:   
    10. a1 focusout target:a1   
    11. a1 focusout relatedTarget:   
    12. a1 DOMFocusOut target:a1   
    13. a1 DOMFocusOut relatedTarget:   
    14. a2 focus target:a2   
    15. a2 focus relatedTarget:   
    16. a2 focusin target:a2   
    17. a2 focusin relatedTarget:   
    18. a2 DOMFocusIn target:a2   
    19. a2 DOMFocusIn relatedTarget:   
    20. keydown : 50  
    a1 focus target:a1
    a1 focus relatedTarget:
    a1 focusin target:a1
    a1 focusin relatedTarget:
    a1 DOMFocusIn target:a1
    a1 DOMFocusIn relatedTarget:
    keydown : 49
    a1 blur target:a1
    a1 blur relatedTarget:
    a1 focusout target:a1
    a1 focusout relatedTarget:
    a1 DOMFocusOut target:a1
    a1 DOMFocusOut relatedTarget:
    a2 focus target:a2
    a2 focus relatedTarget:
    a2 focusin target:a2
    a2 focusin relatedTarget:
    a2 DOMFocusIn target:a2
    a2 DOMFocusIn relatedTarget:
    keydown : 50
     

    只是将 focusxx DOMFocusXx 作为对应 focus,blur 的后面事件触发,没有使用意义。

     

    ie

     

    ie 支持 focusin ,focusout,并且同步触发顺序和规范一致,但是没有 target 以及 relatedTarget 事件属性。

    对于 focus 以及 blur 为异步触发,同样没有 target 以及 relatedTarget 事件属性。

    不支持 DOMFocusIn,DOMFocusOut。

     

    触发顺序:

    Js代码 复制代码 收藏代码
    1. a1 focusin target:null  
    2. a1 focusin relatedTarget:   
    3. keydown : 49   
    4. a1 focus target:null  
    5. a1 focus relatedTarget:   
    6. a1 focusout target:null  
    7. a1 focusout relatedTarget:   
    8. a2 focusin target:null  
    9. a2 focusin relatedTarget:   
    10. keydown : 50   
    11. a1 blur target:null  
    12. a1 blur relatedTarget:   
    13. a2 focus target:null  
    14. a2 focus relatedTarget:  
     a1 focusin target:null
     a1 focusin relatedTarget:
     keydown : 49
     a1 focus target:null
     a1 focus relatedTarget:
     a1 focusout target:null
     a1 focusout relatedTarget:
     a2 focusin target:null
     a2 focusin relatedTarget:
     keydown : 50
     a1 blur target:null
     a1 blur relatedTarget:
     a2 focus target:null
     a2 focus relatedTarget:
    

    updated : 2010-12-10

    一点奇怪的问题:在 ie9 pp7 下,当点击按钮,聚焦页面iframe的body时,iframe body 的 focusin 事件也是异步的!

    例如会出现序列

    Java代码 复制代码 收藏代码
    1. before click   
    2. after click   
    3. body focusin   
    4. body focus  
    before click
    after click
    body focusin
    body focus

     

     而不是

    Java代码 复制代码 收藏代码
    1. before click   
    2. body focusin   
    3. after click   
    4. body focus  
    before click
    body focusin
    after click
    body focus
     

    模拟 focusin/out

     

    这次反过来了,在 focus 或 blur 前有事件触发并且支持子元素冒泡确实非常有用,可是目前 firefox 与 chrome 都不支持或者 触发 顺序不对,另一方面由于标准浏览器支持捕获capture,而捕获阶段恰恰在冒泡阶段前,虽然 focus/blur 不会冒泡,但是捕获阶段还是存在的,那么

     

    handler1

    Js代码 复制代码 收藏代码
    1. element.addEventListener("focus",function(){   
    2. // handler 1   
    3. },true);  
    element.addEventListener("focus",function(){
    // handler 1
    },true);
    

    也就比 handler2

    Js代码 复制代码 收藏代码
    1. element.addEventListener("focus",function(){   
    2. // handler 2   
    3. },false);  
    element.addEventListener("focus",function(){
    // handler 2
    },false);
     

    先触发了,也就相当于 ie 下的

    Js代码 复制代码 收藏代码
    1. element.attachEvent("onfocusin",function(){   
    2. //handler1   
    3. });  
    element.attachEvent("onfocusin",function(){
    //handler1
    });

    并且由于捕获时子元素获得焦点也会通知父元素,那么也就达到了 ie 以及规范规定的冒泡效果,这也正是 kissy 事件模块 用来全平台兼容 focusin/out 的方法了。

     

    应用:

    通过监控 form 即可监控各个输入域,当失去焦点以及得到焦点时进行处理:

    Html代码 复制代码 收藏代码
    1. <form id='f'>  
    2.     <input id='i'/>  
    3.     <input id='i2'/>  
    4. </form>  
    5.   
    6. <script>         
    7.     KISSY.use("node",function(S,Node){   
    8.            
    9.         Node.one("#f").on("focusin",function(ev){   
    10.             console.log("focusin : "+ev.target.attr("id"));   
    11.         });   
    12.         Node.one("#f").on("focusout",function(ev){   
    13.             console.log("focusout : "+ev.target.attr("id"));   
    14.         });   
    15.     });   
    16. </script>  
    <form id='f'>
        <input id='i'/>
        <input id='i2'/>
    </form>
    
    <script>		
    	KISSY.use("node",function(S,Node){
    		
    		Node.one("#f").on("focusin",function(ev){
    			console.log("focusin : "+ev.target.attr("id"));
    		});
    		Node.one("#f").on("focusout",function(ev){
    			console.log("focusout : "+ev.target.attr("id"));
    		});
    	});
    </script>
     
  • 相关阅读:
    【转】NHibernate主键类型介绍
    【转】NHibernate 各种数据库配置
    NHibernate常见错误
    NHibernate 设置主键不自增长
    Oracle 同名字段的该行数据按照创建时间最新的隐藏其他
    不用第三个变量就能交换两个变量值的五个方法
    Java IO 要点总结
    Java API 各个包的内容解释
    Ways to 优化JAVA程序设计和编码,提高JAVA性能
    Java菜鸟入坑学习要点
  • 原文地址:https://www.cnblogs.com/lteal/p/3148115.html
Copyright © 2020-2023  润新知