窗口焦点和模糊事件在 Android 浏览器上无法正常工作

发布于 2025-01-06 05:41:01 字数 1132 浏览 0 评论 0原文

我发现当附加到窗口、文档或正文时,Javascript 焦点和模糊事件在 Android 浏览器上无法正确触发。

我编写了一个简单的测试脚本,该脚本在桌面浏览器上可以正常工作,但在 Android 股票浏览器、Dolphin 和 Opera 移动设备上失败:

<!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>

有趣的是,如果表单输入获得焦点,则事件处理程序会触发,并且在模糊时,模糊事件处理程序触发两次。

有人对此有好的解决方案或解决方法吗?

编辑:预期的结果是,如果我更改浏览器选项卡或更改为另一个应用程序,则应触发模糊事件,如果我返回浏览器选项卡,则应触发焦点事件(这就是它在桌面上的工作方式)

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

静若繁花 2025-01-13 05:41:01

我相信轮询文档的焦点状态可能正是您所寻找的。每 500 毫秒轮询一次并不昂贵,并且可以满足您的需要。如果您想要文档焦点更改几乎立即发出警报,您可以尝试 100 毫秒之类的设置。

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)

演示:https://jsfiddle.net/sanjaydookhoo/1h7gncaf/

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/

林空鹿饮溪 2025-01-13 05:41:01

我刚刚在运行 jellybean 的 Galaxy Nexus 上测试了您的代码(我拥有的一切),该代码运行完美,并且两个事件仅触发一次。

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>';
};​

可能是您的目标是窗口,在大多数移动设备上,窗口本身通常不能“模糊”。确保直接要求元素报告其自身的模糊和焦点事件。

编辑:
另外,请确保在应用事件侦听器之前等待 DOM 准备就绪。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文