168 votes

Application Web pour iPad : Détecter le clavier virtuel en utilisant JavaScript dans Safari ?

Je suis en train d'écrire une application web pour l'iPad ( pas une application normale de l'App Store - il est écrit en utilisant HTML, CSS et JavaScript). Étant donné que le clavier occupe une grande partie de l'écran, il serait logique de modifier la mise en page de l'application pour l'adapter à l'espace restant lorsque le clavier est affiché. Cependant, je n'ai trouvé aucun moyen de détecter si le clavier est affiché ou non.

Ma première idée était de supposer que le clavier est visible lorsqu'un champ de texte a le focus. Cependant, lorsqu'un clavier externe est fixé à un iPad, le clavier virtuel ne s'affiche pas lorsqu'un champ de texte reçoit le focus.

Dans mes expériences, le clavier n'a pas non plus affecté la hauteur ou la hauteur de défilement d'aucun des éléments du DOM, et je n'ai trouvé aucun événement ou propriété propriétaire indiquant si le clavier est visible.

1 votes

Hm, problème intéressant. Essayez d'itérer sur les objets de "window" dans le Safari de l'iPad pour voir s'il y a des objets spéciaux liés au support du clavier.

0 votes

@David cela ne fonctionnera pas, le clavier n'est pas une "fenêtre" Javascript.

2 votes

@KennyTM. Duh. Mais il peut y avoir un drapeau lié à l'affichage du clavier à l'écran dans l'un des objets de la fenêtre. Cela vaut la peine d'essayer.

56voto

LKM Points 2306

J'ai trouvé une solution qui fonctionne, même si elle est un peu moche. Elle ne fonctionnera pas non plus dans toutes les situations, mais elle fonctionne pour moi. Puisque j'adapte la taille de l'interface utilisateur à la taille de la fenêtre de l'iPad, l'utilisateur ne peut normalement pas faire défiler la fenêtre. En d'autres termes, si je fixe le scrollTop de la fenêtre, il restera à 0.

Si, par contre, le clavier est affiché, le défilement fonctionne soudainement. Je peux donc définir scrollTop, tester immédiatement sa valeur, puis la réinitialiser. Voici à quoi cela pourrait ressembler en code, en utilisant jQuery :

$(document).ready(function(){
    $('input').bind('focus',function() {
        $(window).scrollTop(10);
        var keyboard_shown = $(window).scrollTop() > 0;
        $(window).scrollTop(0);

        $('#test').append(keyboard_shown?'keyboard ':'nokeyboard ');
    });
});

Normalement, on s'attendrait à ce qu'il ne soit pas visible pour l'utilisateur. Malheureusement, au moins lors de l'exécution dans le simulateur, l'iPad fait visiblement (mais rapidement) défiler l'écran de haut en bas. Malgré tout, cela fonctionne, du moins dans certaines situations spécifiques.

Je l'ai testé sur un iPad, et cela semble fonctionner correctement.

0 votes

J'ai un problème avec mon application web où lorsque l'entrée est mise au point, l'écran défile un peu vers le haut. J'ai désactivé le défilement, mais l'écran continue de défiler. Avez-vous une idée ? Merci [ stackoverflow.com/questions/6740253/

0 votes

Je ne l'ai pas encore essayé, mais il semble prometteur. Je ne .scrollTop(1) fonctionnerait aussi bien et serait moins évidente ?

0 votes

Oui, scrollTop(1) devrait fonctionner également ; toute valeur supérieure à 0 devrait fonctionner.

36voto

Vous pouvez utiliser le focusout pour détecter l'abandon du clavier. C'est comme le flou, mais avec des bulles. Il se déclenchera lorsque le clavier se ferme (mais aussi dans d'autres cas, bien sûr). Dans Safari et Chrome, l'événement ne peut être enregistré qu'avec addEventListener, et non avec les méthodes existantes. Voici un exemple que j'ai utilisé pour restaurer une application Phonegap après la fermeture du clavier.

 document.addEventListener('focusout', function(e) {window.scrollTo(0, 0)});

Sans cet extrait, le conteneur de l'application restait en position de défilement vers le haut jusqu'au rafraîchissement de la page.

1 votes

La meilleure solution que j'ai trouvée pour mon problème

1 votes

Vous pouvez également utiliser la version 'focusin' pour détecter l'ouverture du clavier.

14voto

Michele Points 131

Une solution légèrement meilleure consiste peut-être à lier (avec jQuery dans mon cas) l'événement "blur" sur les différents champs de saisie.

Ceci parce que lorsque le clavier disparaît, tous les champs du formulaire sont brouillés. Donc, pour ma situation, ce bout de phrase a résolu le problème.

$('input, textarea').bind('blur', function(e) {

       // Keyboard disappeared
       window.scrollTo(0, 1);

});

J'espère que cela vous aidera. Michele

0 votes

Merci pour cette réponse. Je l'ai trouvée utile pour résoudre un problème où le clavier Safari de l'iPad faisait que le curseur de la zone de texte était déplacé (décalé) en dehors de la zone de texte.

14voto

ianh Points 659

En présence d'un clavier à l'écran, si vous mettez l'accent sur un champ de texte situé près du bas de la fenêtre, Safari fera défiler le champ de texte pour l'afficher. Il existe peut-être un moyen d'exploiter ce phénomène pour détecter la présence d'un clavier (en plaçant un minuscule champ de texte en bas de la page qui obtient momentanément la mise au point, ou quelque chose de ce genre).

1 votes

C'est une idée ingénieuse. J'ai trouvé une solution similaire qui utilise également la position de défilement actuelle pour détecter le clavier virtuel.

0 votes

Génial ! tu as sauvé ma journée !

11voto

Hafthor Points 5663

Pendant l'événement focus, vous pouvez dépasser la hauteur du document et, comme par magie, la window.innerHeight est réduite de la hauteur du clavier virtuel. Notez que la taille du clavier virtuel est différente selon qu'il s'agit d'une orientation paysage ou portrait ; vous devrez donc la redétecter lorsqu'elle change. Je vous déconseille de vous souvenir de ces valeurs car l'utilisateur peut connecter/déconnecter un clavier bluetooth à tout moment.

var element = document.getElementById("element"); // the input field
var focused = false;

var virtualKeyboardHeight = function () {
    var sx = document.body.scrollLeft, sy = document.body.scrollTop;
    var naturalHeight = window.innerHeight;
    window.scrollTo(sx, document.body.scrollHeight);
    var keyboardHeight = naturalHeight - window.innerHeight;
    window.scrollTo(sx, sy);
    return keyboardHeight;
};

element.onfocus = function () {
    focused = true;
    setTimeout(function() { 
        element.value = "keyboardHeight = " + virtualKeyboardHeight() 
    }, 1); // to allow for orientation scrolling
};

window.onresize = function () {
    if (focused) {
        element.value = "keyboardHeight = " + virtualKeyboardHeight();
    }
};

element.onblur = function () {
    focused = false;
};

Notez que lorsque l'utilisateur utilise un clavier Bluetooth, la hauteur du clavier est de 44, ce qui correspond à la hauteur de la barre d'outils [précédent][suivant].

Il y a un tout petit peu de scintillement lorsque vous faites cette détection, mais il ne semble pas possible de l'éviter.

6 votes

Je viens d'essayer avec iOS 8.2 et ça ne marche pas ... est-ce que ça a cessé de fonctionner à un moment donné pour les nouveaux iOS ?

1 votes

Cela n'a pas fonctionné pour moi non plus - le redimensionnement n'est pas activé dans iOS9.3.

0 votes

La fonction virtualKeyboardHeight m'a permis d'éviter le défilement d'un champ de recherche qui s'affiche en plein écran sur les appareils mobiles lorsqu'on le tape. Sur iOS, il était toujours poussé hors de l'écran par le clavier lorsque le champ de saisie se trouvait dans les 60 % inférieurs de l'écran. Les autres fonctions de défilement que j'ai essayées ne m'ont pas aidé du tout.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X