J'ai récemment travaillé sur un projet de chat H5 et j'ai rencontré l'un des plus gros pièges : la zone de saisie obtient le focus, le clavier contextuel apparaît et la zone de saisie doit être adsorbée (ou surmontée) sur la méthode de saisie. boîte. Les exigences sont très claires et semblent simples, mais en réalité elles ne le sont pas. Après avoir expérimenté quelques modèles, nous avons constaté qu'il y avait principalement les problèmes suivants :
Explorons une par une les solutions aux problèmes mentionnés ci-dessus.
Obtenez le statut contextuel et rétracté du clavier logicielIl est important de savoir si le clavier logiciel est en haut ou en bas, et le traitement de compatibilité ultérieur doit être basé sur cela. Cependant, H5 ne surveille pas directement les événements natifs du clavier logiciel. Il ne peut surveiller qu'indirectement les performances d'autres aspects de la page en faisant apparaître ou en rétractant le clavier logiciel, sauvant ainsi le pays. De plus, les performances sur IOS et Android sont différentes.
Performances contextuelles du clavier logiciel IOSSur iOS, lorsque la zone de saisie (saisie, zone de texte ou texte enrichi) obtient le focus, le clavier apparaît, la page (vue Web) n'est pas compressée ou la hauteur (hauteur) ne change pas, mais la page (vue Web) comme un tout défile vers le haut. Et la hauteur de défilement maximale (scrollTop) est la hauteur du clavier logiciel.
Performances contextuelles du clavier logiciel AndroidDe même, sur Android, la zone de saisie obtient le focus et le clavier apparaît, mais la hauteur de la page (vue Web) changera. De manière générale, la hauteur est la hauteur de la zone visuelle (hauteur d'origine moins la hauteur du clavier logiciel). ), sauf parce que le contenu de la page est extensible et peut produire un défilement, mais la vue Web elle-même ne peut pas défiler.
Performances de réduction du clavier logiciel IOSLorsque le bouton de rétraction du clavier virtuel ou la zone de page en dehors de la zone de saisie est déclenché, la zone de saisie perd le focus et le clavier virtuel se rétracte.
Performances d'effondrement du clavier logiciel AndroidLorsqu'une zone en dehors de la zone de saisie est déclenchée, la zone de saisie perd le focus et le clavier virtuel est rétracté. Cependant, lorsque le bouton de rétraction du clavier est déclenché, la zone de saisie ne perdra pas le focus et le clavier virtuel sera également rétracté.
Surveillez la fenêtre contextuelle et l'effondrement du clavier virtuelSur la base des différentes performances ci-dessus de l'apparition et de la réduction du clavier sur IOS et Android, nous pouvons effectuer le traitement suivant séparément pour surveiller l'apparition et la réduction du clavier logiciel :
// Jugez le type de périphérique var JudgeDeviceType = function () { var ua = window.navigator.userAgent.toLocaleLowerCase(); var isIOS = /iphone|ipad|ipod/.test(ua); ( ua); return { isIOS : isIOS, isAndroid : isAndroid }}()// Écoutez la fonction contextuelle du clavier logiciel et réduisez les événements de la zone de saisie. ListenKeybord($input) { if (judgeDeviceType.isIOS) { // Le clavier IOS apparaît : les zones de saisie IOS et Android obtiennent le focus et le clavier apparaît $input.addEventListener('focus', function () { console.log(' Clavier IOS Il apparaît ! '); // Opération après l'apparition du clavier IOS}, false) // Le clavier IOS se rétracte : IOS Si vous cliquez en dehors de la zone de saisie ou cliquez sur le bouton de rétraction, la zone de saisie perdra le focus et le clavier se rétractera $input.addEventListener('blur', () => { console.log('Clavier IOS rétracté !') ; // Opération après le pliage du clavier IOS }) } // Le clavier Andriod est plié : lorsque le clavier Andriod apparaît ou se plie, la hauteur de la page change et, sur cette base, le clavier est plié if (judgeDeviceType.isAndroid) { var originHeight = document.documentElement.clientHeight || document.body.clientHeight; window.addEventListener('resize', function () { var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight; if (originHeight < resizeHeight) { console.log('Le clavier Android est rangé !'); // Opération après le rangement du clavier Android} else { console.log('Le clavier Android apparaît ! '); // Opération après l'apparition du clavier Android} originHeight = resizeHeight; false) }}var $inputs = document.querySelectorAll('.input');for (var i = 0; i < $inputs.length; i++) { écouteClébord($inputs[i]);}Lorsque vous ouvrez le clavier virtuel, la zone de saisie défile toujours vers la zone visible.
Parfois, nous créerons un formulaire de saisie avec de nombreux éléments de saisie. La zone de saisie obtient le focus et le clavier contextuel apparaît. Lorsque la zone de saisie est située dans la partie inférieure de la page, sur IOS, la vue Web entière sera enroulée sur une certaine distance afin que la zone de saisie ciblée soit automatiquement dans la zone visible. Cependant, ce ne sera pas le cas sur Android. . Cela modifiera uniquement la hauteur de la page, sans faire défiler l'élément actuellement sélectionné dans la zone visible.
Étant donné que ce qui précède a été implémenté pour surveiller l'apparition et le retrait des claviers IOS et Android, il vous suffit ici de faire défiler (scrollIntoView()) l'élément focus vers la zone visuelle après l'apparition du clavier Android. Pour voir l'effet, vous pouvez cliquer ici.
// Récupère l'élément focus et fait défiler jusqu'à la zone visible function activeElementScrollIntoView(activeElement, delay) { var editable = activeElement.getAttribute('contenteditable') // La zone de saisie, la zone de texte ou le texte enrichi ne défile pas jusqu'à la zone visible après avoir obtenu la zone de focus if (activeElement.tagName == 'INPUT' || activeElement.tagName == 'TEXTAREA' || editable === '' || editable) { setTimeout(function () { activeElement.scrollIntoView(); }, delay) }}// ...// Operate activeElementScrollIntoView($input, 1000);// ... après l'apparition du clavier AndroidÉvoquez un clavier logiciel purement numérique
La zone de saisie du formulaire ci-dessus vous demande de saisir un numéro de téléphone. De la même manière, un clavier numérique apparaîtra. Puisque nous parlons de compatibilité du clavier logiciel, insérons-le ici. Une meilleure solution est la suivante :
<p>Veuillez saisir votre numéro de téléphone mobile</p><input type=tel novalidate=novalidate pattern=[0-9]* class=input>
Si vous utilisez la version IOS12 et V6.7.4+ du navigateur WeChat pour ouvrir la démo de saisie de formulaire ci-dessus, vous serez surpris de constater qu'une fois le clavier rétracté, la page qui défilait initialement vers le haut ne revient pas à la position inférieure, ce qui entraîne le clavier d'origine à rebondir. La position de départ est vide.
En fait, il s'agit d'un bug Apple dans iOS et apparaîtra sur tous les appareils IOS12 fournis avec Xcode10. WeChat a officiellement proposé une solution. Faites simplement défiler la page (vue Web) jusqu'à la position inférieure de la fenêtre (position clientHeight) après la fermeture du clavier logiciel. La démo de saisie du formulaire réparée ci-dessus peut être cliqué ici
console.log('Le clavier IOS est rangé !');// La version 6.7.4+IOS12 du navigateur WeChat montrera qu'une fois le clavier rangé, la vue est poussée vers le haut mais pas vers le bas var wechatInfo = window.navigator.userAgent .match( /MicroMessenger//([/d/.]+)/i);if (!wechatInfo) return;var wechatVersion = wechatInfo[1];var version = (navigator.appVersion).match(/OS (/d+)_(/d+)_?(/d+)?/);if (+wechatVersion.replace(//./g, '') >= 674 && +version[1] >= 12) { window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));}Compatible avec les méthodes de saisie tierces
Cela dit, en fait, plus de la moitié des pièges de la zone de saisie du chat H5 ont été comblés. Examinons ensuite la structure HTML de base de la zone de saisie du chat.
<div class=chat__content> <div> <p>Certains contenus de chat 1</p> </div> <!--Omettre des milliers de lignes de contenu de chat--></div><div class=input__content> <div class =input contenteditable=true></div> <button>Envoyer</button></div>
style
/* Omettre certains styles */.chat__content { height: calc(100% - 40px); margin-bottom: 40px; overflow-y: auto; overflow-x: Hidden;}.input__content { display: flex height: 40px; position : absolue ; gauche : 0 ; droite : 0 ; bas : 0 ; align-items : center;}/* Omettre certains styles*/
C'est très simple, il suffit de diviser la zone de contenu et la zone de saisie. La zone de saisie est positionnée de manière absolue. Selon la méthode de démonstration de saisie du formulaire ci-dessus, il est vrai que la plupart des navigateurs Android fonctionnent bien, mais le test était sur IOS. la méthode de saisie native et pour les méthodes de saisie tierces (telles que la méthode de saisie Sogou), la zone de saisie sera complètement bloquée ; pour le navigateur QQ ou le navigateur WeChat, avec une méthode de saisie tierce, la zone de saisie sera à moitié bloquée ; avec le navigateur Baidu, avec une méthode de saisie tierce, la zone de saisie sera bloquée. Elle sera également entièrement couverte. Pour voir l'effet, vous pouvez visiter ici dans le navigateur correspondant.
Sur UC Browser, après l'apparition du clavier virtuel, la hauteur de la barre de titre au-dessus du navigateur a un effet dynamique de retard de diminution de la hauteur, ce qui fait défiler un peu la vue Web vers le bas et la zone de saisie inférieure défile vers le non- zone visible.
En ce qui concerne la méthode de saisie tierce, il est supposé que le positionnement initial du défilement de la vue Web est incorrect en raison d'un calcul de hauteur incorrect après l'apparition du panneau de la méthode de saisie. En fait, ces deux points sont causés par le fait que la vue Web ne défile pas sur place. Une fois le clavier virtuel affiché, l'élément de focus peut à nouveau défiler vers la zone visible, forçant la vue Web à se mettre en place.
console.log('Le clavier Android apparaît !');activeElementScrollIntoView($input, 1000);Solution de piratage compatible avec le navigateur Android Xiaomi
Sur le navigateur Xiaomi d'Android, après avoir appliqué la solution ci-dessus, j'ai constaté que la zone de saisie du chat était toujours étroitement bloquée et que scrollIntoView() restait toujours immobile. Je suppose donc que c'est en fait parce que le clavier logiciel a défilé vers le bas et que la hauteur de la page est supérieure à la hauteur de la zone visuelle lorsque le clavier logiciel apparaît. De cette façon, la hauteur de la page ne peut être augmentée de force qu'après. le clavier logiciel apparaît pour que la zone de saisie puisse être affichée. Sur la base de ce qui précède, il est compatible avec les méthodes de saisie tierces. Pour voir l'effet, vous pouvez cliquer ici.
// Le clavier Andriod se rétracte : la hauteur de la page changera lorsque le clavier Andriod apparaît ou se rétracte. Sur cette base, la rétraction du clavier est connue si (judgeDeviceType.isAndroid) { var originHeight = document.documentElement.clientHeight || body.clientHeight ; window.addEventListener('resize', function () { var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight; if (originHeight < resizeHeight) { console.log('Le clavier Android est fermé !'); // Résout le problème selon lequel la zone de saisie est toujours bloquée par la méthode de saisie dans le navigateur Xiaomi if (judgeDeviceType.isMiuiBrowser ) { document.body.style.marginBottom = '0px'; } } else { console.log('Le clavier Android apparaît !'); Résolvez le problème selon lequel la zone de saisie est toujours bloquée par la méthode de saisie dans le navigateur Xiaomi if (judgeDeviceType.isMiuiBrowser) { document.body.style.marginBottom = '40px'; } activeElementScrollIntoView($input, 1000 } originHeight = resizeHeight; }, FAUX )}Résumer
La fin du H5 a un long chemin à parcourir et de nombreux pièges, vous devez donc continuer à essayer. Comprendre la différence de performances entre la page contextuelle du clavier logiciel sur IOS et Android est une condition préalable. La deuxième étape consiste à faire défiler l'élément de focus vers la zone visible. En même temps, les différences entre les méthodes de saisie tierces et certains navigateurs. doit être pris en compte.
Ce qui précède représente l’intégralité du contenu de cet article. J’espère qu’il sera utile à l’étude de chacun. J’espère également que tout le monde soutiendra le réseau VeVb Wulin.