简体   繁体   中英

Window focus and blur events not working correctly on Android browser

I found out that Javascript focus and blur events does not fire correctly on the Android browser, when attached to window, document or body.

I wrote a simple test script which is working correctly on desktop browsers, but fails on Android stock browser, Dolphin, and Opera mobile:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
    <title>Focus test</title>

    <script type="text/javascript">

        window.onfocus = function() {
            document.getElementById('console').innerHTML += '<div>Focus event handler fired.</div>';
        };
        window.onblur = function() {
            document.getElementById('console').innerHTML += '<div>Blur event handler fired.</div>';
        };

    </script>
</head>

<body>
    <input id="test" name="test" />
    <div id="console"></div>
</body>

</html>

Interesting thing is, that if the form input is getting focus, the event handler fires, and on blur, the blur event handler fires twice.

Does anyone have a good solution or a workaround for this?

EDIT: The expected result would be, that if I change a browser tab, or change to another app, the blur event should fire, and if I go back to the browser tab, the focus event should fire (that's how it works on desktop)

I just tested your code on a Galaxy Nexus running jellybean (all I have) and this code works perfect, and both events only fire once each.

document.getElementById('test').onfocus = function() {
    document.getElementById('console').innerHTML += '<div>Focus event handler fired.</div>';
};
document.getElementById('test').onblur = function() {
    document.getElementById('console').innerHTML += '<div>Blur event handler fired.</div>';
};​

Could be that you were targeting the window, which on most mobile devices, cannot normally be "blurred" per-se. Make sure you directly ask the element to report its own blur and focus events.

EDIT: Also, make sure you're waiting for the DOM to be ready before applying event listeners.

I believe polling the document for its focus status may be exactly what you are looking for. polling every 500ms is not expensive and will give you what you need. If you would like an Almost immediate alert of document focus change, you can try something like 100ms.

let prevStateIsFocused = null // used to ensure that there is only one execution of a function for either the document focused or not

setInterval(() => {
    if(document.hasFocus()){
        if(prevStateIsFocused !== true){
            console.log('window is focused')
            // execute some function here ...
        }
        prevStateIsFocused = true
    }else{
        if(prevStateIsFocused !== false){
            console.log('window has lost focused, blurred')
            // execute some function here ...
        }
        prevStateIsFocused = false
    }
}, 500)

Demo: https://jsfiddle.net/sanjaydookhoo/1h7gncaf/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM