Firefox .on('focusin') not working for image?

310 Views Asked by At

I've been tinkering with jQuery events and I stumbled upon an very interesting situation (Firefox bug?) that I can't find anywhere explaned. I want to utilize the focus event for certain HTML elements but it seems that there are some limitations, such as:

  • paragraphs, divs (and probably other containers) need the contenteditable attribute to true to make them "focusable"
  • images do not work under Firefox (but they work under Chrome and Opera) even with contenteditable="true". However, adding the attribute tabIndex seems to do the trick, but it's a hack and it doesn't seem like the correct solution.

So, what is the correct behaviour? Is Firefox buggy, or Chrome/Opera's behaviour is too generous, allowing the focus event for everything that is contenteditable? Also, is there some other, less-intrusive, workaround for 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

There are 1 best solutions below

0
On

focusin and focusout are still not supported by firefox

Bug report: 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);
        });
    }

}();