Aujourd'hui, lors du développement d'une page mobile H5, j'ai rencontré le problème que l'interface ne peut pas revenir à sa position d'origine lorsque le clavier est rétracté sur IOS. Les problèmes et symptômes sont décrits en détail ci-dessous :
Structure des pagesLa page en question est une structure de formulaire. Autrement dit, cela ressemble à une structure avec quatre formulaires de saisie sous un div permettant aux utilisateurs de remplir les informations de courrier. similaire:
<div> <input type=text placeholder=Veuillez remplir la province, la ville et le comté/> <input type=text placeholder=Veuillez remplir l'adresse/> <input type=text placeholder=Veuillez remplir le nom/> < input type=text placeholder=Veuillez remplir l'adresse/numéro de contact/></div>
La capture d'écran est la suivante :
La page monte automatiquement lorsque le clavier est affichéLorsque l'utilisateur saisit le numéro de contact sur le téléphone mobile, le clavier de l'iPhone apparaîtra. À ce moment, afin de permettre à l'utilisateur de voir la zone de saisie du téléphone, la page entière sera déplacée vers le haut sur l'iPhone (sinon le clavier). couvrira la zone de saisie du téléphone). À l'heure actuelle, le haut de la page fait en fait partie de la distance qui nous sépare de notre fenêtre d'affichage (nous voyons une rangée de zones de saisie disparaître de l'interface).
La page ne peut pas être restaurée à sa position d'origine lorsque le clavier est ferméCependant, lorsque l'utilisateur termine la saisie et ferme le clavier, même si le clavier est rangé, la position de la page ne sera pas restaurée.
Analyse du problèmeEn fait, cela est dû à l'incapacité d'iOS à empêcher la partie de la page qui défile hors de la fenêtre de tomber lorsque le clavier est rétracté. A ce moment, l'utilisateur peut faire glisser la page vers l'arrière avec son doigt.
Mais l’expérience n’a finalement pas été bonne.
Pour résoudre ce problème, nous pouvons appeler window.scrollTo(0, 0)
lorsque le curseur de l'utilisateur quitte la zone de saisie pour faire défiler la page et l'aligner avec le haut de la fenêtre, obtenant ainsi l'effet d'accueil de la page.
Alors maintenant, le problème est d'ajouter des événements de flou aux quatre zones de saisie du formulaire, puis d'appeler window.scrollTo
dans le gestionnaire. Cependant, qu'il soit ajouté via @blur
de Vue ou via des opérations DOM, 4 écouteurs d'événements doivent être ajoutés, ce qui n'est pas très élégant. Naturellement, nous avons pensé à utiliser des proxys d'événements.
Autrement dit, nous plaçons l'écouteur d'événement sur l'élément supérieur ; puis définissons une fonction inputBlur pour attendre le déclenchement.
<div @blur=inputBlur> <input type=text placeholder=Veuillez remplir la province, la ville et le comté/> <input type=text placeholder=Veuillez remplir l'adresse/> <input type=text placeholder=Veuillez remplir le name/> <input type=text placeholder=Veuillez remplir votre numéro de contact/></div>
En conséquence, nous avons constaté que notre écouteur d’événements n’avait pas réussi à se déclencher. La raison en est que l'événement blur
de la zone de saisie ne peut pas faire de bulles.
Après interrogation, il a été constaté que les deux événements DOM focus
et blur
ne pouvaient pas apparaître dans la spécification. De la même manière, il existe deux autres événements focusin
et focusout
qui peuvent bouillonner.
Certains articles sur Internet mentionnent que focusin
et focusout
sont des événements DOM pris en charge uniquement par les navigateurs IE. En fait, quand on regarde le document MDN, on constate que ces deux événements sont devenus un standard dans la spécification DOM 3, et sont supportés par un grand nombre de navigateurs.
Par conséquent, pour résoudre le problème de manière décisive à travers ces deux événements, nous l'avons modifié focusout
<div @focusout=inputBlur> <input type=text placeholder=Veuillez remplir la province, la ville et le comté/> <input type=text placeholder=Veuillez remplir l'adresse/> <input type=text placeholder=Veuillez remplir le name/> <input type=text placeholder=Veuillez remplir votre numéro de contact/></div>
Ensuite, implémentez notre gestionnaire d'événements :
inputBlur(e) { // Tout d'abord, déterminez si l'élément cible qui déclenche l'événement est une zone de saisie. Nous nous concentrons uniquement sur le comportement de la zone de saisie. if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { window.scrollTo(0,0 } });
À ce stade, notre problème est résolu. Lorsque vous saisissez du contenu à partir de la zone de saisie puis cliquez sur Terminer sur le clavier pour fermer le clavier, l'effet est conforme à nos attentes.
Cependant, après des tests sur les téléphones mobiles, nous avons constaté que lorsque nous passons directement de 电话输入框
à 姓名输入框
, la page tremble. Poursuivons l'analyse.
En fait, la raison pour laquelle les deux zones de saisie tremblent lors de la commutation est également très simple. Parce que lorsque nous basculons entre les deux zones de saisie ci-dessus, la page déclenchera d'abord blur
de 电话输入框
, puis déclenchera focus
de 姓名输入框
. Dans ce cas, lorsque le flou se produit, notre window.scrollTo(0,0)
sera déclenché, provoquant le défilement de la page vers le bas, puis 姓名输入框
sera focalisée, de sorte que le clavier continuera à apparaître --- ceci fera remonter la page vers le haut.
En fait, lors du basculement entre deux zones de saisie, nous n'avons pas besoin de déclencher le comportement window.scrollTo
lorsque la première zone de saisie est floue. Modifions donc notre code pour que lorsque l'opération de changement de zone de saisie se produit, le comportement de la première zone de saisie puisse être coupé. Ici, nous utilisons setTimeout pour résoudre :
<div @focusout=inputBlur @focusin=inputFocus> <input type=text placeholder=Veuillez remplir la province, la ville et le comté/> <input type=text placeholder=Veuillez remplir l'adresse/> <input type=text placeholder= Veuillez remplir le nom/> < input type=text placeholder=Veuillez remplir votre numéro de contact/></div>
inputBlur(e) { // Tout d'abord, déterminez si l'élément cible qui déclenche l'événement est une zone de saisie. Nous nous concentrons uniquement sur le comportement de la zone de saisie. if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { // La zone de saisie perd le focus et le clavier IOS doit être poussé hors du faire défiler une partie de la page pour la restaurer. Faites défiler la page vers le haut de la fenêtre et alignez-la console.log('set timer') this.timer = setTimeout(() => { console.log('timer trigger') window.scrollTo(0,0); }, 0) } }, inputFocus(e) { // Si focus, supprime le minuteur de la zone de saisie précédente if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { clearTimeout(this.timer } });
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.