Firefox .on('focusin')不适用于图像?

时间:2015-06-16 14:30:46

标签: javascript jquery events focus

我一直在修补jQuery事件,我偶然发现了一个非常有趣的情况(Firefox bug?),我无法在任何地方找到解释。我想对某些HTML元素使用焦点事件,但似乎存在一些限制,例如:

  • 段落,div(可能还有其他容器)需要 contenteditable 属性为true才能使它们“可聚焦”
  • 图像在Firefox下不起作用(但它们在Chrome和Opera下工作),即使 contenteditable =“true”也是如此。但是,添加属性tabIndex似乎可以解决问题,但这是一个黑客攻击,它似乎不是正确的解决方案。

那么,正确的行为是什么?是Firefox有问题,还是Chrome / Opera的行为过于慷慨,允许焦点事件适合所有可满足的事情?另外,Firefox还有其他一些不太干扰的解决方法吗?

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
</head>
<body>
<img src="http://investorplace.com/wp-content/uploads/2014/02/bacon.jpg" id="img" contenteditable="true"  />

<div id="p" contenteditable="true">text test text</div>

<input id="inp" />
</body>
</html>

http://pastebin.com/WeJ4XS8t

1 个答案:

答案 0 :(得分:1)

firefox

仍然不支持

focusinfocusout

错误报告: https://bugzilla.mozilla.org/show_bug.cgi?id=687787

Polyfill:https://gist.github.com/nuxodin/9250e56a3ce6c0446efa

!function(){
    var w = window, 
        d = w.document;

    if( w.onfocusin === undefined ){
        d.addEventListener('focus'    ,addPolyfill    ,true);
        d.addEventListener('blur'     ,addPolyfill    ,true);
        d.addEventListener('focusin'  ,removePolyfill ,true);
        d.addEventListener('focusout' ,removePolyfill ,true);
    }  
    function addPolyfill(e){
        var type = e.type === 'focus' ? 'focusin' : 'focusout';
        var event = new CustomEvent(type, { bubbles:true, cancelable:false });
        event.c1Generated = true;
        e.target.dispatchEvent( event );
    }
    function removePolyfill(e){
        if(!e.c1Generated){ // focus after focusin, so chrome will the first time trigger tow times focusin
            d.removeEventListener('focus'    ,addPolyfill    ,true);
            d.removeEventListener('blur'     ,addPolyfill    ,true);
            d.removeEventListener('focusin'  ,removePolyfill ,true);
            d.removeEventListener('focusout' ,removePolyfill ,true);
        }
        setTimeout(function(){
            d.removeEventListener('focusin'  ,removePolyfill ,true);
            d.removeEventListener('focusout' ,removePolyfill ,true);
        });
    }

}();