57

Mobile Safari で、遅延時間を設定した後、テキスト フィールドに集中できません。問題を示すサンプルコードを添付しています。ボタンをクリックして .focus() をトリガーすると、すべてが期待どおりに機能します。setTimeout 関数のように、コールバックにフォーカスを当てると、モバイル サファリでのみ失敗します。他のすべてのブラウザーでは、遅延があり、その後フォーカスが発生します。

紛らわしいことに、モバイルサファリでも「focusin」イベントがトリガーされます。これ (および SO の同様のコメント) は、モバイル サファリのバグだと思います。どんなご案内でも承ります。

エミュレータと iPhone 3GS/4 iOS4 でテストしました。

HTML の例:

<!DOCTYPE html> 
  <html lang='en'> 
    <head> 
      <title>Autofocus tests</title> 
      <meta content='width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0' name='viewport'> 
      <meta content='yes' name='apple-mobile-web-app-capable'> 
    </head> 
    <body>
      <h1> 
        Show keyboard without user focus and select text:
      </h1> 
      <p> 
        <button id='focus-test-button'> 
          Should focus on input when you click me after .5 second
        </button> 
        <input id='focus-test-input' type='number' value='20'> 
      </p> 
      <script type="text/javascript"> 
        //<![CDATA[
        var button = document.getElementById('focus-test-button');
        var input  = document.getElementById('focus-test-input');

        input.addEventListener('focusin', function(event) {
          console.log('focus');
          console.log(event);
        });

        button.addEventListener('click', function() {
          // *** If triggered immediately - functionality occurs as expected
          // input.focus();
          // *** If called by callback - triggers the focusin event, but does not bring up keyboard or cursor
          var t = setTimeout("input.focus();",500);
        });
        //]]>
      </script>
    </body>
  </html>

~Similar~ SO の質問:

4

6 に答える 6

84

これはバグというよりはモバイルSafariの機能だと思います。FastClickに関する作業で、同僚と私は、呼び出しスタックの最初の関数がプログラム以外のイベントによってトリガーされた場合にのみ、iOSが関数内から他の要素にフォーカスをトリガーできることを発見しました。あなたの場合、呼び出しsetTimeoutは新しい呼び出しスタックを開始し、セキュリティメカニズムが作動して、入力にフォーカスを設定できないようにします。

iOSでは、入力要素にフォーカスを設定するとキーボードが表示されることに注意してください。そのため、Googleのように、ページの読み込み時に入力要素にフォーカスを設定するすべてのWebページは、iOSで使用するのが非常に面倒です。Appleはこれを防ぐために何かをしなければならないと決めたと思います。だから私は@DAに同意しません:これはバグではなく機能です。

これに対する既知の回避策はないため、遅延を使用するという考えを捨てる必要があります。

2012年8月の更新:

iOS 5以降、合成されたクリックイベントによってトリガーされるハンドラーは、入力要素へのフォーカスをトリガーできます。更新されたFastClick入力フォーカスの例を試してください。

于 2011-09-07T10:13:38.340 に答える
6

元のイベントが setTimeout ではなくユーザーの操作によるものである場合にのみクリック イベントをディスパッチすることで、キーボードを上げることができました。その結果、タッチエンドイベントからキーボードを上げることはできますが、タイムアウトからは上げることができないと思います。

于 2012-09-11T15:46:12.027 に答える
2

サイトをホーム画面に追加し、このリンクでサイトを開いた場合にのみ focus() が機能するようです。

于 2013-07-04T14:27:05.757 に答える
0

イベント マップ内の 2 つの個別のイベントにアタッチすることで .focus() を動作させることができましたが、ちょっとハッキーです。

FastClick.js を追加すると、iOS では次のようになります。.focus() は、イベントに関連付けられた関数によってアクティブ化された場合にのみ機能します。ただし、フォーカスは、jQuery の .focus() を使用するときに実際に呼び出されるモバイル サファリのイベント マップのイベントでもあります。SO 冗長になり、オブジェクトの focus イベントに別の .focus() をアタッチして、確実にプルスルーすることができます。これは、DOM で入力を作成する場合に特に効果的です。私は最近 MeteorJS のプログラミングが好きです。

Template.templateName.events({
    "click button":function(){
        Session.set("makeButtonVisible",true);
        $("input.created").focus();
    },
    "focus input.created":function(){
        $("input.created").focus();
    }
});

うまくいけば、これが誰かに役立つことを願っています.これを理解するのに2時間ほどかかりました.

編集: 特に MeteorJS の場合、.focus() はイベントから呼び出す必要があるため、Template.templateName.rendered 関数も使用できません。しかし、何らかの理由で、jQuery を介して入力を追加すると、イベント内でそれに集中できます。それが行く方法だと思います。これは私がやったことです:

Template.templateName.events({
    "click button":function(){
        $("body").append("<input class='created' type='tel'>");
        $("input.created").focus();
    }
});
于 2013-09-08T06:47:38.697 に答える
0

マットの回答に追加します。少なくとも iOS 5.1 の Safari では、この問題は修正されています。あなたのFastClick作品、つまり、クリック イベントを合成しても、フォーカスが失われることはありません。focus()ただし、これは、単一のコードをすべての iOS バージョンで動作させたい人には役に立ちません。

于 2012-06-16T00:14:55.657 に答える