網站搜尋

javascript - Safari iOS - 點擊外部時輸入框不會失去焦點(Blur 不觸發)


我不知道為什麼當我點擊輸入框以外的地方(在黃色的段落上)時,blur 事件不會觸發。所以鍵盤無法關閉。我能觸發它的唯一方式是當我點擊 body(在片段中是藍色)。

我放了很多 console.log 來除錯。

更奇怪的是,當我移除文件上的事件點擊時,對 body 的點擊就不再起作用了!

這個問題發生在 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>

答案#1

我找到了一個破解方法:

document.body.firstElementChild.tabIndex = 1

這使得 body 中的第一個元素可以聚焦,因此當你點擊輸入框「外部」時,它會失去焦點。同時,你不會在該聚焦元素上看到任何視覺錯誤,因為沒有定義樣式(除非你的 body 第一個子元素不是 div)。

答案#2

一個不那麼臨時的解決方案可能是調用

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 更安全(也就是確定是預期的輸入元素),但我發現兩者都可以正常使用。