22

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)

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
istvan.halmen
  • 3,320
  • 1
  • 23
  • 29
  • Have you tried jQuery? It does a lot of normalisation of events so they are more consistent across different browsers. – Walf May 09 '12 at 00:14
  • Yes, I started with jQuery, I just stripped the example down to plain javascript, to exclude eventual jQuery bugs. – istvan.halmen May 09 '12 at 06:58
  • What is the expected result of your example on an Android browser? – Uooo Aug 23 '12 at 10:11
  • Perhaps the [Page visibility API](https://developer.mozilla.org/en-US/docs/Web/Events/visibilitychange) would help? I don't seem to be able to come up with a consistent way to make onblur work. – JosiahDaniels Mar 14 '15 at 20:16
  • Ooops. Just realized this is an old thread. – JosiahDaniels Mar 14 '15 at 20:20

2 Answers2

1

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/

0

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.

Kyle Somogyi
  • 278
  • 2
  • 10
  • 3
    I know that it works on document elements, but I specifically wanted to use on the window element. 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) – istvan.halmen Oct 05 '12 at 05:28