web-dev-qa-db-fra.com

Comment se concentrer par programme sur un champ de texte lors du chargement de page pour un safari mobile?

Note: En raison d'un changement lié au travail, je ne peux plus vérifier les réponses postées ici. Très probablement, je ne pourrai jamais accepter une réponse en bas. Les informations affichées ici sont utiles pour l’OMI, je vais donc les laisser telles quelles. Si vous pensez connaître une réponse, n'hésitez pas à y répondre et nous laisserons à la communauté le soin de décider lesquelles sont utiles.


Contexte

Je développe une application Web autonome pour iPod Touch. L'une de mes exigences est de me concentrer sur un champ de texte lors du chargement d'une page afin qu'un utilisateur puisse effectuer une tâche de manière continue (par exemple avec un lecteur de code à barres).

Problème

Le problème est que se concentre sur le champ de texte en question, mais que le clavier ne monte pas . Y at-il une solution de contournement pour cela? Ou est-ce une conception de Apple?

Sample Html

Je ne sais pas comment insérer cela dans un extrait de code, mais c'est là que j'ai expérimenté:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0.0">

    <meta name="Apple-mobile-web-app-capable" content="yes">
    <link rel="Apple-touch-icon" href="https://cdn57.androidauthority.net/wp-content/uploads/2016/06/Android-win-2-300x162.png">

    <title>TESTING</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

    <script>
        // javascript goes here
    </script>
</head>
<body>

    <section id="content">

        <div class="container" style="margin-top: 50px;" >

            <p>Testing textfield focus</p>

            <form method="POST">
                <div class="row">
                    <div class="col-xs-12">
                        <input type="text" class="form-control first-responder" />
                    </div>
                    <div class="col-xs-12">
                        <button type="submit" class="btn" style="width: 100%" >OK</button>
                    </div>
                </div>
            </form>

        </div>

    </section>

</body>
</html>

Je vois ceci sur Safari, puis je l’ajoute à l’écran d’accueil de sorte qu’il devienne une application Web autonome.

Tentatives

J'ai essayé de chercher des solutions, le premier (j'ai perdu le lien) a suggéré d'essayer les délais d'attente de la manière suivante:

$(function () {
    var firstResponder = $(".first-responder");
    setTimeout(function() {
        firstResponder.focus();

    }, 1000);

})

Un autre des solutions J'ai trouvé suggéré de définir la plage de sélection comme suit:

$(function () {
    var firstResponder = $(".first-responder");
    setTimeout(function() {
        firstResponder[0].setSelectionRange(0, 9999);

    }, 1000);

})

There avait également été suggéré de le lier à un clic comme ceci:

$(function () {
    var firstResponder = $(".first-responder");
    firstResponder.on('click', function() {
        firstResponder.focus();
    });

    firstResponder.focus().click();
})

J'ai aussi essayé de déclencher un touchstart comme ceci:

$(function () {
    var firstResponder = $(".first-responder");
    firstResponder.on('touchstart', function() {
        firstResponder.focus();
    });

    firstResponder.trigger('touchstart');
})

J'ai aussi essayé avec un simple appel ajax comme ça (peu importe la réussite/l'erreur. Tout ce que je voulais faire était de se concentrer après l'appel ajax):

function doAjax() {
    var firstResponder = $(".first-responder");

    $.ajax({
        url: "#",
        method: "POST",
        dataType: "json",
        success: function(result) {
            firstResponder.focus();
        },
        error: function(request, error) {
            firstResponder.focus();         
        }
    });
}

Je suis un peu désespéré alors j'ai essayé en mettant quelques css aussi:

user-select: text;
-webkit-user-select: text;

Ces solutions fonctionnaient sur iOS 9.1 (sauf la version css) mais toutes ont échoué sur iOS 11.1.1. J'ai essayé de combiner diverses solutions, de définir des délais d'attente, etc., mais aucune ne semble fonctionner. Comme je l'ai noté, il fait la focalisation car je peux voir que les bordures du champ de texte deviennent bleu, ce qui signifie qu'il a la focalisation. Mais J'ai besoin que le clavier soit affiché aussi.

Ce comportement semble être soit un bug ou un facilité d'utilisation / sécuritéfonctionnalité . Si cela est voulu (c'est-à-dire une fonctionnalité de sécurité), existe-t-il une documentation officielle d'Apple qui en parle?

Addendum

Si vous pensez que le lecteur de codes à barres pourrait être le problème, ce n'est pas vrai. Dans le projet sur lequel je travaille, le lecteur de codes à barres remplace le clavier natif. En théorie, même sans le code à barres, tant que je suis capable d’afficher le clavier au chargement de la page, je devrais être en mesure de répondre à mes besoins.

La tâche continue est possible car le lecteur de code à barres peut inclure un Enter clé après la lecture du code à barres, soumettant ainsi le formulaire sur lequel le champ de texte est activé. Une fois la page rechargée, si le champ de texte devient automatiquement centré, il suffit à l'utilisateur de lire un autre code à barres. La page est soumise à nouveau, rechargée, mise au point automatique et le cycle peut être répété.

14
Keale

Après quelques essais difficiles, j'ai trouvé un moyen qui fonctionnait dans l'iphone 7 de ma petite amie avec iOS 11, maintenant je ne sais pas si cela répond à vos besoins, mais le clavier virtuel apparaît!

C'est le test html:

<input type='text' id='foo' onclick="this.focus();">
<button id="button">Click here</button>

C'est le javascript:

function popKeyboard(input) {
  input.focus();
  input.setSelectionRange(0, 0);
}

$("#button").on("click", function() {
  popKeyboard($("#foo"));
});

Et c'est le violon .

Oh et CanIUse juste au cas où!

Maintenant, ce que nous faisons est que lorsque nous cliquons sur le bouton, cela équivaut à une entrée utilisateur, car le clavier ne peut être affiché que si l'utilisateur donne une entrée (sous Android et ios), nous lançons la fonction popKeyboard, qui active selectionRange to 0,0, ce qui signifie que le curseur est positionné sur 0 et que le clavier devrait apparaître.

Cela a été testé dans Android et un iPhone 7 avec IOS 11.

Méfiez-vous qu’elle m’ait prévenue que son iOS 11 n’était pas complètement à jour, mais si cela fonctionne, merci de me le signaler!

3
Tosindo

Examinez cette question avec la solution: jQuery Définir la position du curseur dans la zone de texte

Si vous utilisez les fonctions décrites dans cette solution juste après le ajax ready event, le clavier s'affichera même dans Safari sur iOS 11.2.2.

2
Florian Chrometz

Avez-vous essayé cela?

 $(function(){
    $('input.form-control.first-responder').first().focus();
  });

Le sélecteur est restreint par first () et garantit qu'il n'est pas affecté par d'autres classes similaires de la page.

2
s1mpl3

Utilisez ajaxComplete au lieu de load ou ready

Je viens de charger 1 fichier via ajax et la méthode ajaxComplete que j'ai définie pour le champ d'entrée.

Ceci fonctionne exemple, j'espère que cela fonctionnera pour vous.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0.0">

    <meta name="Apple-mobile-web-app-capable" content="yes">
    <link rel="Apple-touch-icon" href="https://cdn57.androidauthority.net/wp-content/uploads/2016/06/Android-win-2-300x162.png">

    <title>TESTING</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
	
	<style>
	span{
		display:none;
	}
	</style>
	
    <script>
	$(document).ready(function(){
	
		$("span").load("https://www.w3schools.com/xml/cd_catalog.xml");
	
		$(document).ajaxComplete(function(){
			$(".first-responder")[0].focus();
		});
	});
    </script>
</head>
<body>

    <section id="content">

        <div class="container" style="margin-top: 50px;" >

            <p>Testing textfield focus</p>

            <form method="POST">
                <div class="row">
                    <div class="col-xs-12">
                        <input type="text" class="form-control first-responder" />
                    </div>
                    <div class="col-xs-12">
                        <button type="submit" class="btn" style="width: 100%" >OK</button>
                    </div>
                </div>
            </form>

        </div>

    </section>
<span></span>
</body>
</html>

1
Tushar Acharekar

si vous vous concentrez, vous devez vous assurer que le navigateur est complètement chargé et pas seulement onDOMContentReady pour ce faire, utilisez l'événement standard load car celui-ci se déclenche une fois le chargement terminé (le rendu est terminé)

En raison de la bizarrerie des navigateurs de kit Web modernes (chrome, iOS11), un délai a été ajouté pour une raison quelconque, l’événement load se déclenche avant que le navigateur ne soit complètement chargé. Cependant, je m'assure de toujours utiliser l'événement load comme point de départ.

(function($){
  $(function(){
      window.addEventListener("load", function(){
        setTimeout(function(){  $(".first-responder").focus();  }, 150);
      });
  })
})(jQuery);

https://jsfiddle.net/barkermn01/xzua65jd/1/

1
Martin Barker

Je viens de faire quelques expériences. Dans iOS 11, .focus () n'afficherait pas le clavier si vous tentiez de le définir sur le tout premier contrôle sans que l'utilisateur ne touche à un contrôle pour la première fois. Cependant, .focus () afficherait le clavier si vous n'aviez pas .blur () sur le document actuel.activeElement avant que vous .focus () sur un autre élément.

Le code ci-dessous a fonctionné pour moi à partir de cette touche (lecteur de code à barres, ScanBoard) pour iPod: -

$(window).keypress(function (e) {
    if (e.which === 13) {
        switch (true) {
            case window.location.href.indexOf('FindReplenishmentLocation') > -1:
            case window.location.href.indexOf('ConfirmReplenishmentLocation') > -1:
            case window.location.href.indexOf('ConfirmReplenishmentPickFace') > -1:
                if (document.activeElement.id === 'pickFaceLocationTextBox' || document.activeElement.id === 'bulkLocationTextBox') {
                    if ($('#skuTextBox').val()) {
                        $('#skuTextBox').focus().select();
                    }
                    else {
                        if (isMobile) {
                            $('#skuTextBox').focus().select();
                        }
                        else {
                            $('#skuTextBox').focus();
                        }
                    }
                }
                else {
                    if (window.location.href.indexOf('ConfirmReplenishmentPickFace') > -1) {
                        if ($('#qtyPutAwayNumericTextBox').val()) {
                            $('#qtyPutAwayNumericTextBox').focus().select();
                        }
                        else {
                            if (isMobile) {
                                $('#qtyPutAwayNumericTextBox').focus().select();
                            }
                            else {
                                $('#qtyPutAwayNumericTextBox').focus();
                            }
                        }
                    }
                    else {
                        $('#next-btn').trigger('click');
                    }
                }
                break;                
            default:
                break;
        }

        e.preventDefault();
    }
});
0
danjackknife