Tenho trabalhado em um projeto de bate-papo H5 recentemente e encontrei uma das maiores armadilhas: a caixa de entrada fica em foco, o teclado virtual aparece e a caixa de entrada precisa ser adsorvida (ou coberta) no método de entrada caixa. Os requisitos são muito claros e parecem simples, mas na verdade não são. Depois de experimentar alguns modelos, descobrimos que existem principalmente os seguintes problemas:
Vamos explorar as soluções para os problemas mencionados acima, uma por uma.
Obtenha o status de pop-up e retração do teclado virtualÉ importante saber se o teclado virtual está ativo ou inativo, e o processamento de compatibilidade subsequente deve ser baseado nisso. No entanto, o H5 não monitora diretamente os eventos nativos do teclado virtual. Ele só pode monitorar indiretamente o desempenho de outros aspectos da página abrindo ou retraindo o teclado virtual, salvando o país. Além disso, o desempenho no IOS e no Android é diferente.
Desempenho pop-up do teclado virtual do IOSNo iOS, quando a caixa de entrada (input, textarea ou rich text) recebe o foco, o teclado aparece, a página (webview) não é compactada ou a altura (height) não muda, mas a página (webview) como um todo rola para cima e a altura máxima de rolagem (scrollTop) é a altura do teclado virtual.
Desempenho do pop-up do teclado virtual do AndroidDa mesma forma, no Android, a caixa de entrada fica em foco e o teclado aparece, mas a altura da página (visualização na web) muda. De modo geral, a altura é a altura da área visual (altura original menos a altura do teclado virtual). ), exceto porque o conteúdo da página está em expansão, pode produzir rolagem, mas a visualização da web em si não pode rolar.
Desempenho de colapso do teclado virtual IOSQuando o botão de retração no teclado virtual ou na área da página fora da caixa de entrada é acionado, a caixa de entrada perde o foco e o teclado virtual é retraído.
Desempenho de colapso do teclado virtual do AndroidQuando uma área fora da caixa de entrada é acionada, a caixa de entrada perde o foco e o teclado virtual é retraído. No entanto, quando o botão de retração do teclado é acionado, a caixa de entrada não perderá o foco e o teclado virtual também será retraído.
Monitore o pop-up e o colapso do teclado virtualCom base nos diferentes desempenhos acima de pop-up e recolhimento do teclado no IOS e Android, podemos realizar o seguinte processamento separadamente para monitorar o pop-up e recolhimento do teclado virtual:
// Julgue o tipo de dispositivo var juizDeviceType = function () { var ua = window.navigator.userAgent.toLocaleLowerCase(); ( ua); return { isIOS: isIOS, isAndroid: isAndroid }}() // Ouça o pop-up do teclado virtual e a função de eventos de recolhimento da caixa de entrada listenKeybord($input) { if (judgeDeviceType.isIOS) { // O teclado IOS aparece: as caixas de entrada IOS e Android ganham foco e o teclado aparece $input.addEventListener('focus', function () { console.log(' Teclado IOS Aparece! '); // Operação após o teclado IOS aparecer}, false) // Teclado IOS retrai: IOS Se você clicar fora da caixa de entrada ou clicar no botão retrair, a caixa de entrada perderá o foco e o teclado será retraído $input.addEventListener('blur', () => { console.log('IOS keyboard retracted!') ; // Operação após o teclado IOS ser dobrado }) } // O teclado Andriod é dobrado: Quando o teclado Andriod aparece ou dobra, a altura da página muda e, com base nisso, o teclado é dobrado 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('O teclado Android foi guardado!'); // Operação após o teclado Android ser guardado} else { console.log('Teclado Android aparece! '); // Operação após o teclado Android aparecer} originHeight = resizeHeight }, false) }}var $inputs = document.querySelectorAll('.input');for (var i = 0; i < $inputs.length; i++) { ouvirKeybord($inputs[i]);} Ao abrir o teclado virtual, a caixa de entrada sempre rola para a área visível.Às vezes faremos um formulário de entrada com muitos itens de entrada. A caixa de entrada ganha o foco e o teclado virtual aparece. Quando a caixa de entrada está localizada na parte inferior da página, no IOS, todo o webview será enrolado a uma certa distância para que a caixa de entrada em foco fique automaticamente na área visível. Porém, este não será o caso no Android. . Isso apenas alterará a altura da página, sem rolar para o elemento atualmente em foco na área visível.
Como o acima foi implementado para monitorar o pop-up e retração dos teclados IOS e Android, aqui você só precisa rolar (scrollIntoView()) o elemento de foco para a área visual depois que o teclado Android aparecer. Para ver o efeito, você pode clicar aqui.
// Obtenha o elemento de foco e role até a área visível function activeElementScrollIntoView(activeElement, delay) { var editable = activeElement.getAttribute('contenteditable') // A caixa de entrada, textarea ou rich text não rola para a área visível após obter a área de foco if (activeElement.tagName == 'INPUT' || activeElement.tagName == 'TEXTAREA' || editable === '' || editable) { setTimeout(function () { activeElement.scrollIntoView(); }, delay) }}// ...// Operate activeElementScrollIntoView($input, 1000);// ... depois que o teclado Android aparecer Evoque um teclado virtual numérico puroA caixa de entrada do formulário acima exige que você insira um número de telefone, um teclado virtual numérico aparecerá. Como falamos sobre compatibilidade de teclado virtual, vamos inseri-lo aqui. Uma solução melhor é a seguinte:
<p>Insira o número do seu celular</p><input type=tel novalidate=novalidate pattern=[0-9]* class=input>
Se você usar a versão IOS12 e V6.7.4+ do navegador WeChat para abrir a demonstração de entrada do formulário acima, ficará surpreso ao descobrir que depois que o teclado é retraído, a página que foi originalmente rolada para cima não retorna à posição inferior, causando o teclado original para saltar. A posição inicial está vazia.
Na verdade, este é um bug da Apple no iOS e aparecerá em todos os dispositivos IOS12 empacotados com Xcode10. O WeChat deu oficialmente uma solução. Basta rolar a página (webview) de volta para a posição inferior da janela (posição clientHeight) depois que o teclado virtual for fechado. A demonstração de entrada do formulário reparada acima pode ser clicada aqui
console.log('IOS keyboard is guarded!'); // O navegador WeChat versão 6.7.4+IOS12 mostrará que depois que o teclado for guardado, a visualização será empurrada para cima, mas não para baixo var wechatInfo = window.navigator.userAgent .match( /MicroMessenger//([/d/.]+)/i);if (!wechatInfo) return;var wechatVersion = wechatInfo[1];var versão = (navigator.appVersion).match(/OS (/d+)_(/d+)_?(/d+)?/);if (+wechatVersion.replace(//./g, '') >= 674 && +versão[1] >= 12) { window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));} Compatível com métodos de entrada de terceirosTendo dito tudo acima, na verdade, mais da metade das armadilhas da caixa de entrada do chat H5 foram preenchidas. A seguir, vamos dar uma olhada na estrutura HTML básica da caixa de entrada do chat.
<div class=chat__content> <div> <p>Algum conteúdo de bate-papo 1</p> </div> <!--Omitir milhares de linhas de conteúdo de bate-papo--></div><div class=input__content> <div class =input contenteditable=true></div> <button>Enviar</button></div>
estilo
/* Omitir alguns estilos */.chat__content { height: calc(100% - 40px); margin-bottom: 40px; posição: absoluta esquerda: 0; direita: 0; inferior: 0; alinhar-itens: centro;}/* Omitir alguns estilos*/É muito simples, basta dividir a área de conteúdo e a área de entrada. A área de entrada está absolutamente posicionada. De acordo com o método de demonstração de entrada do formulário acima, é verdade que a maioria dos navegadores Android estão bem, mas o teste foi no UC Browser. o método de entrada nativo e Para métodos de entrada de terceiros (como o método de entrada Sogou), a caixa de entrada será completamente bloqueada para o navegador QQ ou navegador WeChat, com um método de entrada de terceiros, a caixa de entrada será parcialmente bloqueada; com o navegador Baidu, com um método de entrada de terceiros, a caixa de entrada será bloqueada. Também será completamente coberta. Para visualizar o efeito, você pode visitar aqui no navegador correspondente.
No UC Browser, depois que o teclado virtual aparece, a altura da barra de título acima do navegador tem um efeito dinâmico de atraso de diminuição da altura, o que faz com que o webview role um pouco para baixo e a caixa de entrada inferior role para o não- área visível.
Quanto ao método de entrada de terceiros, especula-se que o posicionamento inicial de rolagem do webview está incorreto devido a um cálculo de altura incorreto após o painel do método de entrada aparecer. Na verdade, esses dois pontos são causados pelo fato de o webview não rolar no lugar. Depois que o teclado virtual aparece, o elemento de foco pode ser rolado para a área visível novamente, forçando o webview a se posicionar no lugar.
console.log('Teclado Android aparece!');activeElementScrollIntoView($input, 1000); Solução de hack compatível com navegador Android XiaomiNo navegador Xiaomi do Android, depois de aplicar a solução acima, descobri que a caixa de entrada do bate-papo ainda estava totalmente bloqueada e scrollIntoView() ainda permanecia imóvel. Então, acho que é porque o teclado virtual foi rolado para baixo e a altura da página é maior que a altura da área visual quando o teclado virtual aparece. Dessa forma, a altura da página só pode ser aumentada à força depois. o teclado virtual aparece para que a caixa de entrada possa ser exibida. Com base no exposto, é compatível com métodos de entrada de terceiros. Para visualizar o efeito, você pode clicar aqui.
// Teclado Andriod retrai: A altura da página mudará quando o teclado Andriod aparecer ou retrair Com base nisso, a retração do teclado é conhecida 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('O teclado Android está fechado!'); // Corrige o problema de que a caixa de entrada ainda está bloqueada pelo método de entrada no navegador Xiaomi if (judgeDeviceType.isMiuiBrowser). ) { document.body.style.marginBottom = '0px'; } else { console.log('O teclado Android aparece!'); Corrija o problema de que a caixa de entrada ainda está bloqueada pelo método de entrada no navegador Xiaomi if (judgeDeviceType.isMiuiBrowser) { document.body.style.marginBottom = '40px' } activeElementScrollIntoView($input, 1000 } originHeight = resizeHeight; }, falso)} ResumirO final do H5 tem um longo caminho pela frente e muitas armadilhas, então você precisa continuar tentando. Compreender a diferença de desempenho entre a página pop-up do teclado virtual no IOS e no Android é um pré-requisito. A segunda etapa é rolar o elemento de foco para a área visível. deve ser levado em conta.
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.