Текстовое поле автофокуса Mobile Safari - PullRequest
54 голосов
/ 09 июня 2011

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

~ Аналогично ~ SOвопросы:

Ответы [ 6 ]

80 голосов
/ 07 сентября 2011

Я думаю, что это особенность мобильного Safari, а не ошибка. В нашей работе над FastClick мы с коллегами обнаружили, что iOS будет позволять фокусироваться только на других элементах, изнутри функции, если первая функция в стеке вызовов была вызвана непрограммным событие. В вашем случае вызов setTimeout запускает новый стек вызовов, и включается механизм безопасности, чтобы вы не смогли сконцентрировать внимание на вводе.

Помните, что при настройке iOS фокус на элементе ввода вызывает клавиатуру - поэтому все те веб-страницы, которые фокусируются на элементе ввода при загрузке страницы, как это делает Google, были бы крайне раздражающими для использования на iOS. Я думаю, Apple решила, что они должны сделать что-то, чтобы предотвратить это. Поэтому я не согласен с @DA: это функция, а не ошибка.

Обходного пути для этого не существует, поэтому вам придется отказаться от идеи использования задержки.

Обновление за август 2012 года:

Начиная с iOS 5, обработчики, запускаемые синтезированными событиями щелчка, могут активировать фокус на элементах ввода. Попробуйте обновленный пример фокуса ввода FastClick .

5 голосов
/ 11 сентября 2012

Мне удалось поднять клавиатуру, отправив событие щелчка только тогда, когда исходное событие было от взаимодействия с пользователем, а не от setTimeout. Я полагаю, что в результате вы можете поднять клавиатуру после кассового события, но все же не по таймауту.

1 голос
/ 04 июля 2013

Похоже, что focus () работает, только если вы добавили сайт на домашний экран и открыли сайт по этой ссылке.

0 голосов
/ 14 сентября 2013

Вы ответили сами. Вам нужно просто вызвать, если вы используете Jquery. Изменить фокус () на триггере («фокус»); в любой части вашего кода.

$ ( "# searchField") триггер ( "фокус").

0 голосов
/ 08 сентября 2013

Я был в состоянии заставить .focus () работать, привязав его к двум отдельным событиям на карте событий, но это отчасти хакерски.

После добавления FastClick.js, это то, что происходит в iOS: .focus () работает только тогда, когда он активируется функцией, прикрепленной к событию. НО фокус также является событием в карте событий мобильного сафари, которое фактически вызывается, когда вы используете jfuery .focus (). Таким образом, вы можете быть лишним и прикрепить еще один .focus () к событию focus объекта, чтобы убедиться, что он проходит. Это особенно хорошо работает, когда вы создаете вход в DOM. В последнее время мне нравится программировать для MeteorJS, вот как выглядит решение:

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

Надеюсь, это кому-нибудь пригодится, мне понадобилось около двух часов, чтобы понять это.

EDIT: Ну, в частности, для MeteorJS вы не можете использовать функцию Template.templateName.rendered, потому что .focus () должен вызываться из события. НО по какой-то причине, когда вы добавляете вход через jQuery, вы можете сосредоточиться на нем внутри события. Думаю, это путь. Вот что я в итоге сделал:

Template.templateName.events({
    "click button":function(){
        $("body").append("<input class='created' type='tel'>");
        $("input.created").focus();
    }
});
0 голосов
/ 16 июня 2012

Добавление к Мэтту ответа. По крайней мере, в Safari на iOS 5.1 эта проблема исправлена. Ваш FastClick работает, то есть синтез события щелчка не подведет фокус. Однако это не помогает людям, которые хотят, чтобы их единственный код focus() работал на всех версиях iOS, вздох.

...