Hoje, ao desenvolver uma página móvel H5, encontrei o problema de que a interface não consegue retornar à sua posição original quando o teclado é retraído no IOS. Os problemas e sintomas são descritos em detalhes abaixo:
Estrutura da páginaA página em questão é uma estrutura de formulário. Ou seja, é semelhante a uma estrutura com quatro formulários de entrada sob uma div para os usuários preencherem as informações de mailing. semelhante:
<div> <input type=text placeholder=Por favor preencha a província, cidade e condado/> <input type=text placeholder=Por favor preencha o endereço/> <input type=text placeholder=Por favor preencha o nome/> < input type=text placeholder=Por favor preencha o endereço/número de contato/></div>
A captura de tela é a seguinte:
A página sobe automaticamente quando o teclado é abertoQuando o usuário digita o número de contato no celular, o teclado do iPhone irá aparecer. Neste momento, para permitir que o usuário veja a caixa de entrada do telefone, toda a página será movida para cima no iPhone (caso contrário, o teclado). cobrirá a caixa de entrada do telefone). Neste momento, o topo da página está, na verdade, a uma distância de nossa janela de visualização (vemos uma linha de caixas de entrada desaparecendo da interface).
A página não pode ser restaurada à sua posição original quando o teclado é fechadoNo entanto, quando o usuário conclui a entrada e fecha o teclado, embora o teclado seja guardado, a posição da página não será restaurada.
Análise de problemasNa verdade, isso é causado pela incapacidade do iOS de evitar que parte da página role para fora da janela de visualização e caia quando o teclado é retraído. Neste momento, o usuário pode arrastar a página de volta com o dedo.
Mas a experiência não foi boa, afinal.
Para resolver esse problema, podemos chamar window.scrollTo(0, 0) quando o cursor do usuário sai da caixa de entrada para rolar a página para alinhá-la com o topo da janela de visualização, obtendo assim o efeito inicial da página.
Portanto, agora o problema é adicionar eventos de desfoque a todas as quatro caixas de entrada do formulário e, em seguida, chamar window.scrollTo no manipulador. No entanto, quer seja adicionado através do @blur do Vue ou através de operações DOM, quatro ouvintes de eventos devem ser adicionados, o que não é muito elegante. Naturalmente, pensamos em usar proxies de eventos.
Ou seja, colocamos o ouvinte de evento no elemento superior e depois definimos uma função inputBlur para aguardar o disparo.
<div @blur=inputBlur> <input type=text placeholder=Por favor preencha a província, cidade e condado/> <input type=text placeholder=Por favor preencha o endereço/> <input type=text placeholder=Por favor preencha o name/> <input type=text placeholder=Por favor preencha seu número de contato/></div>
Como resultado, descobrimos que nosso ouvinte de evento não foi acionado. A razão é que o evento blur da caixa de entrada não pode borbulhar.
Após consulta, descobriu-se que o focus e blur dos dois eventos DOM não podem borbulhar na especificação. Semelhante a este, existem dois outros eventos focusin e focusout que podem borbulhar.
Alguns artigos na Internet mencionaram que focusin e focusout são eventos DOM suportados apenas por navegadores IE. Na verdade, quando olhamos para o documento MDN, descobrimos que esses dois eventos se tornaram um padrão na especificação DOM 3 e são suportados por um grande número de navegadores.
Portanto, para resolver o problema de forma decisiva através destes dois eventos, mudamos focusout
<div @focusout=inputBlur> <input type=text placeholder=Por favor preencha a província, cidade e condado/> <input type=text placeholder=Por favor preencha o endereço/> <input type=text placeholder=Por favor preencha o name/> <input type=text placeholder=Por favor preencha seu número de contato/></div>
Em seguida, implemente nosso manipulador de eventos:
inputBlur(e) { // Primeiro, determine se o elemento alvo que aciona o evento é uma caixa de entrada. Nós nos concentramos apenas no comportamento da caixa de entrada. if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'entrada') { window.scrollTo(0,0);Neste momento, nosso problema está resolvido. Ao inserir o conteúdo da caixa de entrada e clicar em Concluir no teclado para fechá-lo, o efeito está de acordo com nossas expectativas.
No entanto, após testar em telefones celulares, descobrimos que quando mudamos diretamente da 电话输入框para 姓名输入框, a página fica trêmula. Vamos continuar a análise.
Na verdade, a razão pela qual as duas caixas de entrada tremem ao alternar também é muito simples. Porque quando alternamos entre as duas caixas de entrada acima, a página acionará primeiro blur 电话输入框e, em seguida, acionará focus da 姓名输入框. Neste caso, quando ocorrer desfoque, nosso window.scrollTo(0,0) será acionado, fazendo com que a página role para baixo, e então 姓名输入框será focada, então o teclado continuará a aparecer --- isto fará com que a página se mova para cima novamente.
Na verdade, ao alternar entre duas caixas de entrada, não precisamos acionar o comportamento window.scrollTo quando a primeira caixa de entrada estiver desfocada. Então, vamos modificar nosso código para que, quando ocorrer a operação de troca da caixa de entrada, o comportamento da primeira caixa de entrada possa ser interrompido. Aqui usamos setTimeout para resolver:
<div @focusout=inputBlur @focusin=inputFocus> <input type=text placeholder=Por favor preencha a província, cidade e condado/> <input type=text placeholder=Por favor preencha o endereço/> <input type=text placeholder= Por favor preencha o nome/> < input type=text placeholder=Por favor preencha seu número de contato/></div>
inputBlur(e) { // Primeiro, determine se o elemento alvo que aciona o evento é uma caixa de entrada. Nós nos concentramos apenas no comportamento da caixa de entrada. if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { // A caixa de entrada perde o foco e o teclado IOS precisa ser empurrado para fora do rolando parte da página para restaurá-la. Role a página até o topo da janela e alinhe-a console.log('set timer') this.timer = setTimeout(() => { console.log('timer trigger') window.scrollTo(0,0); }, 0) } }, inputFocus(e) { // Se estiver em foco, remova o cronômetro da caixa de entrada anterior if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'entrada') { clearTimeout(this.timer);O texto acima é todo o conteúdo deste artigo. Espero que seja útil para o estudo de todos. Também espero que todos apoiem a Rede VeVb Wulin.