Dans iOS8 en utilisant .focus () affichera le clavier virtuel et la page de défilement après la touche

Avant iOS8, l'utilisation de la méthode Javascript.focus .focus() sur un élément de saisie semble n'avoir aucun effet (le clavier virtuel ne s'affichera pas). Après la dernière version d'iOS 8, l'exécution de la méthode .focus() n'a pas eu d'effet sur le chargement de la page, mais une fois qu'un utilisateur a touché n'importe où sur l'écran, le clavier virtuel apparaît instantanément et fait défiler la page vers l'élément en foyer. (Ceci est également un problème lorsque j'utilise l'attribut HTML "autofocus")

Cette modification a causé des problèmes avec les utilisateurs d'iOS8 sur mon site. Lorsqu'un utilisateur tente de cliquer sur un bouton de ma page, l'apparition soudaine du clavier et du clavier les fait cligner involontairement sur un bouton qui était plus bas sur l'écran.

Je suppose que c'est un bogue dans iOS8 et n'était pas une fonction intentionnelle, ma question est de savoir quelle est la solution la plus efficace pour résoudre ce problème?

Dois-je vérifier navigator.userAgent pour voir si l'appareil est iOS8, chaque fois que j'utilise la méthode .focus() ?

Il semble que vous gagnez un bug iOS 8. Dans iOS7, Safari aurait (apparemment) ignoré ou gardé des éléments qui ne fonctionnaient pas avant la mise en page. Ceci inclut à la fois <input autofocus> et input.focus() qui se produisent jusqu'à un certain point, éventuellement chargement de page (j'ai testé uniquement avec un script en ligne).

Dans iOS 8, Safari semble maintenant se rappeler que l'élément a été concentré, mais ne l'a pas réellement concentré jusqu'à un événement touchant. Il envoie alors aveuglément un événement de clic à n'importe quel élément reçu le retournement.

Les deux navigateurs se comportent de la même façon pour input.focus() se produisant après la charge de la page. Ils zooment tous les deux vers l'élément et portent le clavier.

Tests:

La bonne nouvelle est que vous devez être préoccupé par un nouveau comportement sur les éléments que vous souhaitez préfocurer. Les autres bonnes nouvelles sont que, alors que vous devrez utiliser une solution d'agent utilisateur-agent, vous pouvez l'utiliser pour toutes les versions iOS car elles se comportaient déjà comme si vous n'étiez pas de mise au point automatique:

 if (!/iPad|iPhone|iPod/g.test(navigator.userAgent)) { element.focus(); } 

Cela semble être l'approche que http://www.google.com utilise en fonction de certains tests basiques d'agent utilisateur:

  • Mac Book Pro: autofocus avant chargement de la page.
  • IPhone: pas d'autofocus
  • IPad: pas d'autofocus
  • Kit Kat (Android): mise au point après chargement de la page, éventuellement détection supplémentaire pour la présence de clavier logiciel.

Si vous ne l'avez pas, vous devriez aller de l'avant et déposer un radar avec Apple à l' adresse https://bugreport.apple.com .

Si vous développez un projet Cordova, vous pouvez le réparer en ajoutant cette ligne

 <preference name="KeyboardDisplayRequiresUserAction" value="false" /> 

À votre fichier config.xml . Testé dans IOS 8.3 et IOS 8.4

Il semble que dans iOS 8, il y a eu un changement d'API sur la gestion par défaut pour la commande javascript focus (). Si votre application est une application hybride dans laquelle vous avez un contrôle direct sur la façade de la page Web d'Apple, ci-dessous est directement à partir de documents sur les pommes.

Une valeur booléenne indiquant si le contenu Web peut afficher par programme le clavier.

[MyWebView setKeyboardDisplayRequiresUserAction: YES];

Lorsque cette propriété est définie sur OUI, l'utilisateur doit exploiter explicitement les éléments de la vue Web pour afficher le clavier (ou toute autre vue d'entrée pertinente) pour cet élément. Lorsqu'il est défini sur NON, un événement de mise au point sur un élément fait apparaître automatiquement la vue d'entrée et associée à cet élément.

La valeur par défaut de cette propriété est OUI.

À partir du dernier paragraphe, il semble que cet appel de méthode ne soit pas strictement pour le clavier. Cela indique que c'est pour les vues d'entrée à travers le tableau, c'est-à-dire le menu déroulant et le sélecteur de date, etc.

Il semble bien qu'il y ait un bug car cet appel de méthode ne fonctionne pas actuellement pour moi. Le comportement actuel que je reçois correspond comme s'il ne parvient pas à NO.

J'ai une solution:

  1. Désactiver toutes les entrées
  2. Activez l'entrée que vous souhaitez concentrer
  3. Mettre l'accent sur cette entrée
  4. Réactivez toutes les autres entrées

Voici un monkeypatch conditionnel pour jQuery.focus donc vous n'avez pas besoin d'ajouter le test userAgent partout.

JavaScript

 if (/iPad|iPhone|iPod/g.test(navigator.userAgent)) { (function($) { return $.fn.focus = function() { return arguments[0]; }; })(jQuery); } 

CoffeeScript

 if /iPad|iPhone|iPod/g.test navigator.userAgent (($) -> $.fn.focus = -> arguments[0] )(jQuery) 

Remarque: Je renvoie des arguments[0] afin de ne pas casser le chaînage de méthode tel que $(el).focus().doSomethingElse()

J'ai enregistré un bug à ce sujet dans le Apple Bug Reporter et ils l'ont fermé en double, ce qui est un signe qu'ils travaillent à résoudre ce problème. Malheureusement, ils ne m'ont pas donné plus d'informations sur l'élément en double ou sur le problème lui-même. Je ne peux que voir l'état de l'élément en double, qui est ouvert.