Cross-browser: detect blur event on window

2019-03-25 02:50发布

问题:

I just read, I think all the thread that deals with this subject, and I can't find a real solution to my problem. I need to detect when the browser window loses its focus, i.e. a blur event. I've tried all the scripts on stackoverflow, but there doesn't seem to be a proper cross-browser approach.

Firefox is the problematic browser here.

A common approach using jQuery is:

window.onblur = function() { 
   console.log('blur'); 
}
//Or the jQuery equivalent:
jQuery(window).blur(function(){
    console.log('blur');
});

This works in Chrome, IE and Opera, but Firefox doesn't detect the event.

Is there a proper cross-browser way to detect a window blur event? Or, asked differently, is there a way to detect a window blur event with the Firefox browser?


Related questions and research:

  • See Firefox 3 window focus and blur
  • According to the following github articles, jQuery has discontinued support for Firefox blur testing:
    • https://github.com/jquery/jquery/pull/1423
    • http://bugs.jquery.com/ticket/13363

回答1:

I tried both:

document.addEventListener('blur', function(){console.log('blur')});

and

window.addEventListener('blur', function(){console.log('blur')});

and they both worked in my version of FF (33.1).

Here's the jsfiddle: http://jsfiddle.net/hzdd06eh/

Click inside the "run" window and then click outside it to trigger the effect.



回答2:

It appears that jQuery no longer supports these tests for FireFox:

  • jQuery bug ticket is here: http://bugs.jquery.com/ticket/13363
  • jQuery close/deprecation commit is here: https://github.com/jquery/jquery/pull/1423

I am searching for a better way to support Firefox blur eventing, but until I find a better approach, this is a more current status relative to the original accepted answer.



回答3:

The document.hasFocus (MDN) is an implementation that can resolve the problem with Firefox, but in Opera it isn't supported. So, a combined approach can reach out the problem you are facing.

The function below exemplifies how can you use this method:

function getDocumentFocus() {
    return document.hasFocus();
}

Since your question isn't clear enough about the application (timed, pub/sub system, event driven, etc), you can use the function above in several ways.

For example, a timed verification can be like the one implemented on this fiddle (JSFiddle).



回答4:

You can use jQuery's blur method on window, like so:

$(document).ready(function() {
  $(window).blur(function() {
    // Put your blur logic here
    alert("blur!");
  });
});

This works in Firefox, IE, Chrome and Opera.



回答5:

I tried using the addEventListener DOM function

window.addEventListener('blur', function(){console.log('blur')});
window.addEventListener('click', function(event){console.log(event.clientX)});

I got it to work after the first blur. but it didnt work when I didnt have the click function attached to it. There might be some kind of refresh that happens when a click function is interpreted



回答6:

Here is an alternative solution to your question but it uses the Page Visibility API and Solution is Cross Browser compatible.

(function() {
    var hidden = "hidden";

    // Standards:
    if (hidden in document)
        document.addEventListener("visibilitychange", onchange);
    else if ((hidden = "mozHidden") in document)
        document.addEventListener("mozvisibilitychange", onchange);
    else if ((hidden = "webkitHidden") in document)
        document.addEventListener("webkitvisibilitychange", onchange);
    else if ((hidden = "msHidden") in document)
        document.addEventListener("msvisibilitychange", onchange);
    // IE 9 and lower:
    else if ("onfocusin" in document)
        document.onfocusin = document.onfocusout = onchange;
    // All others:
    else
        window.onpageshow = window.onpagehide = window.onfocus = window.onblur = onchange;

    function onchange(evt) {
        var v = "visible",
            h = "hidden",
            evtMap = {
                focus: v,
                focusin: v,
                pageshow: v,
                blur: h,
                focusout: h,
                pagehide: h
            };

        evt = evt || window.event;
        if (evt.type in evtMap) {
            console.log(evtMap[evt.type]);
        } else {

            console.log(this[hidden] ? "hidden" : "visible");
        }
    }

    // set the initial state (but only if browser supports the Page Visibility API)
    if (document[hidden] !== undefined)
        onchange({
            type: document[hidden] ? "blur" : "focus"
        });
})();