4

I want to be able to detect when arbitrary elements loose focus in JavaScript, so I can build an in-line editing tool similar to jEdit. I can't depend on jQuery for this library, so I need a native method for doing it.

I looked at onblur, which would seem to be the right thing but MDN has a note that suggests it may be IE specific?

In contrast to MSIE--in which almost all kinds of elements receive the blur event--almost all kinds of elements on Gecko browsers do NOT work with this event.

Which elements will/wont work with this, is there a better way to detect such things?

If blur works, should the docs at https://developer.mozilla.org/en-US/docs/DOM/element.onblur be changed?

ForbesLindesay
  • 10,482
  • 3
  • 47
  • 74

2 Answers2

3

You can use an onfocusout on the body element. The difference between onblur and onfocusout is that the latter bubbles up, so you don't have to install it for every node that you want.

However onfocusout is not cross-browser and is IE's feature, not a standard. I don't know of any problems with setting onblur in current browsers, except that it doesn't bubble.

The only hack to be notified whenever a blur occurs is for you to poll the document.activeElement and firing events when you see changes. See Detect which form input has focus using JavaScript or jQuery

Community
  • 1
  • 1
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
0

In order to detect the loss of focus, for accessibility audits, I personally use the ugly combination of all the following:

(function($){

var focusCounter = 0;

/* Set focus outline (CSS, jQuery): */
$("*").on("focus","body",function(e){$(e.target).css("outline","5px solid orange");$(e.target).on("blur",function(e){$(e.target).css("outline","none");})});

/* Log keypress */
$(document).on('keydown',function(e){
    console.log("========= KEYDOWN ", e.key, " ==================");
});

/* Log currently focused element (On start) */
console.log("CURRENT: ",document.activeElement);

/* Log focused element (On focus) */
document.addEventListener("focus",function(){
    console.log(
        "[ " + (focusCounter++).toString() + " ]",
        "FOCUSED: ",
        "<" + document.activeElement.nodeName + ">",
        ($.trim($(document.activeElement).text())? $.trim($(document.activeElement).text()) : $.trim($(document.activeElement).val())).replace(/(\r\n|\n|\r)/gm, "").substring(0, 30) + '...',
        document.activeElement
    );

},true);

/* Try to detect loss of focus (Works in Chrome) */
document.addEventListener("focusout", function(event){console.log((!event.relatedTarget)?"⚠ FOCUS LOST":"");});

/* Fallback, checks in intervals if the focus is still active/lost e.g. if onfocus or onfocusout didn't work */
(function(){setInterval(function(){console.log('interval check: ',(document.body===document.activeElement)?"FOCUS LOST":"ok");},8500);})();

})(jQuery);

Idea: All of those I set as a bookmarklet so I can easily access it

Hrvoje Golcic
  • 3,446
  • 1
  • 29
  • 33