Safari IOS -输入不会失去焦点点击外(模糊不触发)



我不知道为什么当我点击输入文本(在黄色段落上)时模糊事件不触发。所以键盘不能关闭。我可以触发它的唯一方法是当我点击主体(代码片段中的蓝色部分)。

我放了很多console.log用于调试。

更奇怪的是,当我删除事件点击文档,点击主体不再工作了!

这个问题发生在Safari IOS上。我在Iphone 6上测试过。

你知道吗?

谢谢你的帮助

<!DOCTYPE html>
<html lang="en" style="height:200px; background:blue">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Document</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
</head>
<body style="height:200px; background:gray">
    <form action=""  style="background:purple">
      <input type="text" name="test" id="test">
    </form>
    <p  style="height:50px; background:yellow" >Paragraph</p>
    <script>
        $(document).ready(function() {
            $(document).on('click', function() {
                console.log('document click')
            });
            $('input').click(function(event) {
                console.log("input click");
            });
            $('input').blur(function(event) {
                console.log('input blur');
            });
            $('input').focusout(function(event) {
                console.log('input focustout')
            });
            $('body').on('click', function(event) {
                console.log('body click');
                console.log(event);
            });
        });
    </script>
</body>
</html>

我找到了一个hack:

document.body.firstElementChild.tabIndex = 1

这使得主体中的第一个元素可聚焦,因此当您单击"外部"输入时,它将失去焦点。同时,由于没有定义样式(除非你的第一个body子元素不是div),你不会在焦点元素上看到任何视觉故障

一个不那么俗套的解决方案可能是调用

document.activeElement.blur()

中的事件侦听器,该事件侦听器在<input />元素外部的单击时触发。activeElement有很好的浏览器支持。

您可能还需要在事件侦听器中检查预期的输入当前是否与

之类的内容有焦点。
if (document.activeElement.id === 'foo') document.activeElement.blur()

if (document.activeElement.hasAttribute('bar')) document.activeElement.blur()

确保在输入框外点击时不会随机模糊其他活动元素。

2019年12月7日更新

有一个更简单的解决方案。与blur不同,mouseleave事件在移动Safari上触发,如果您在输入元素外点击。如果你正在使用React,它就像

一样简单
<input onMouseLeave={e => e.target.blur()} />

或者,在纯JS中:

const input = document.getElementById('foo')
input.addEventListener('mouseleave', e => e.target.blur())

event.currentTarget.blur()可能比event.target更安全(即肯定是预期的输入元素),但我发现两者都很好。

最新更新