最近 H5 チャット プロジェクトに取り組んでいますが、最大の落とし穴の 1 つに遭遇しました。それは、入力ボックスにフォーカスがあり、ソフト キーボードがポップアップし、入力ボックスを入力メソッドに吸着 (または上書き) する必要があるということです。箱。要件は非常に明確で単純に見えますが、実際はそうではありません。いくつかのモデルを試した結果、主に次の問題があることがわかりました。
上記の問題の解決策を 1 つずつ検討してみましょう。
ソフトキーボードのポップアップとリトラクトの状態を取得します。ソフト キーボードが上か下かを知ることが重要であり、その後の互換性処理はこれに基づいて行う必要があります。ただし、H5 はソフト キーボードのネイティブ イベントを直接監視せず、ソフト キーボードをポップアップまたは格納することによって、ページの他の側面のパフォーマンスを間接的に監視することしかできません。また、IOSとAndroidではパフォーマンスが異なります。
IOSソフトキーボードポップアップパフォーマンスiOS では、入力ボックス (入力、テキストエリア、またはリッチ テキスト) がフォーカスを取得すると、キーボードがポップアップし、ページ (Web ビュー) は圧縮されず、高さ (高さ) も変更されませんが、ページ (Web ビュー) は次のように表示されます。全体が上にスクロールし、最大スクロール高さ (scrollTop) がソフト キーボードの高さになります。
Android ソフト キーボードのポップアップ パフォーマンス同様に、Android では、入力ボックスにフォーカスが設定され、キーボードがポップアップしますが、ページ (Web ビュー) の高さは変更されます。一般的に、高さは視覚領域の高さ (元の高さからソフト キーボードの高さを引いたもの) になります。 )、ただし、ページ コンテンツが次の場合を除きます。 エキスパンドするとスクロールが生成されますが、Web ビュー自体はスクロールできません。
IOS ソフトキーボードの折りたたみパフォーマンスソフト キーボードの格納ボタン、または入力ボックスの外側のページ領域がトリガーされると、入力ボックスはフォーカスを失い、ソフト キーボードは格納されます。
Android ソフト キーボードの折りたたみパフォーマンス入力ボックスの外側の領域がトリガーされると、入力ボックスはフォーカスを失い、ソフト キーボードは格納されます。ただし、キーボードの格納ボタンがトリガーされても、入力ボックスはフォーカスを失いません。また、ソフト キーボードも格納されます。
ソフトキーボードのポップアップと折りたたみを監視するIOS と Android でのキーボードのポップアップと折りたたみの上記のさまざまなパフォーマンスに基づいて、次の処理を個別に実行して、ソフト キーボードのポップアップと折りたたみを監視できます。
// デバイスの種類を判定 var judgeDeviceType = function () { var ua = window.navigator.userAgent.toLocaleLowerCase(); var isIOS = /iphone|ipad|ipod/.test(ua); ( ua); return { isIOS: isIOS, isAndroid: isAndroid }}()// ソフト キーボード ポップアップをリッスンし、入力ボックスのイベント関数を折りたたむlistenKeybord($input) { if (judgeDeviceType.isIOS) { // IOS キーボードがポップアップします: IOS および Android の入力ボックスがフォーカスを取得し、キーボードがポップアップします $input.addEventListener('focus', function () { console.log(' IOS キーボード ポップアップします! '); // IOS キーボードがポップアップした後の操作 }, false) // IOS キーボードが格納されます: IOS入力ボックスの外側をクリックするか、格納ボタンをクリックすると、入力ボックスはフォーカスを失い、キーボードが格納されます。 $input.addEventListener('blur', () => { console.log('IOS キーボードが格納されました!') ; // IOS キーボードを折りたたんだ後の動作 }) } // Andriod キーボードを折りたたむ: Andriod キーボードがポップアップまたは折りたたむと、ページの高さが変更され、これに基づいてキーボードが折りたたまれます if (judgeDeviceType.isAndroid) { varoriginHeight = document.documentElement.clientHeight || document.body.clientHeight; window.addEventListener('resize', function () { varsizeHeight = document.documentElement.clientHeight || document.body.clientHeight; if (originHeight < assignHeight) { console.log('Android キーボードをしまいました!') // Android キーボードをしまった後の操作} else { console.log('Android キーボードがポップアップします! '); // Android キーボードがポップアップした後の操作} OriginHeight = ResizeHeight; }, false) }}var $inputs = document.querySelectorAll('.input');for (var i = 0; i < $inputs.length; i++) { listenKeybord($inputs[i]);}ソフト キーボードをポップアップすると、入力ボックスは常に表示領域までスクロールします。
多くの入力項目を含む入力フォームを作成することがあります。入力ボックスにフォーカスが置かれ、ソフト キーボードが表示されます。 IOS では、入力ボックスがページの下部にある場合、Web ビュー全体が一定の距離だけロールアップされ、フォーカスされた入力ボックスが自動的に表示領域に表示されます。ただし、Android ではこれは当てはまりません。現在フォーカスされている要素までスクロールせずに、ページの高さを変更するだけです。
上記は、IOS および Android キーボードのポップアップと格納を監視するために実装されているため、ここでは、Android キーボードがポップアップした後にフォーカス要素をビジュアル領域にスクロール (scrollIntoView()) するだけで済みます。効果を確認するには、ここをクリックしてください。
// フォーカス要素を取得し、表示領域までスクロールします function activeElementScrollIntoView(activeElement, late) { var editable = activeElement.getAttribute('contenteditable') // 取得後、入力ボックス、テキストエリア、またはリッチ テキストは表示領域までスクロールしませんフォーカスエリア if (activeElement.tagName == 'INPUT' || activeElement.tagName == 'TEXTAREA' || editable === '' || editable) { setTimeout(function () { activeElement.scrollIntoView(); }, late) }}// ...// Operate activeElementScrollIntoView($input, 1000);// ... Android キーボードがポップアップした後純粋な数値ソフトキーボードを呼び出す
上のフォーム入力ボックスでは、電話番号を入力する必要があります。これと同様に、数値ソフト キーボードが表示されます。ソフト キーボードの互換性について説明するので、ここに入力しましょう。より良い解決策は次のとおりです。
<p>携帯電話番号を入力してください</p><input type=tel novalidate=novalidate pattern=[0-9]* class=input>
IOS12 および V6.7.4+ バージョンの WeChat ブラウザを使用して上記のフォーム入力デモを開くと、キーボードを引っ込めた後、最初に上にスクロールしたページが一番下の位置に戻らないことに驚くでしょう。バウンスする元のキーボード。開始位置は空です。
実際、これは iOS の Apple のバグであり、Xcode10 がパッケージ化されたすべての IOS12 デバイスに発生します。 WeChat は公式に解決策を提供しています。ソフト キーボードを閉じた後、ページ (Web ビュー) をウィンドウの一番下の位置 (clientHeight 位置) までスクロールして戻します。修復された上記のフォーム入力デモはここをクリックできます
console.log('IOS キーボードが片付けられています!');// WeChat ブラウザ バージョン 6.7.4+IOS12 では、キーボードが片付けられた後、ビューが上に押し上げられますが、下には押し上げられないことが表示されます 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));}サードパーティの入力方法との互換性
ここまで述べてきましたが、実際には、H5 チャット入力ボックスの落とし穴の半分以上は埋められています。次に、チャット入力ボックスの基本的な HTML 構造を見てみましょう。
<div class=chat__content> <div> <p>一部のチャット コンテンツ 1</p> </div> <!--数千行のチャット コンテンツを省略します--></div><div class=input__content> <div class =input contenteditable=true></div> <button>送信</button></div>
スタイル
/* 一部のスタイルを省略します */.chat__content { height: calc(100% - 40px); margin-bottom: 40px; overflow-y: auto; overflow-x: hidden; }.input__content { display: flex height: 40px;位置: 絶対; 左: 0; 下: 0; }/* 一部のスタイルを省略します*/
非常に簡単で、入力エリアを絶対配置するだけです。上記のフォーム入力デモの方法によれば、確かにほとんどの Android ブラウザで問題ありませんが、テストは UC Browser と連携しました。ネイティブ入力メソッドとサードパーティ入力メソッド (Sogou 入力メソッドなど) の場合、入力ボックスは完全にブロックされます。QQ ブラウザまたは WeChat ブラウザの場合、サードパーティ入力メソッドの場合、入力ボックスは半分ブロックされます。 Baidu ブラウザでは、サードパーティの入力方法を使用すると、入力ボックスも完全にブロックされます。効果を確認するには、対応するブラウザでここにアクセスしてください。
UC ブラウザでは、ソフト キーボードがポップアップした後、ブラウザ上のタイトル バーの高さが減少するという遅延動的効果があり、これにより Web ビューが少し下にスクロールし、下部の入力ボックスが非表示にスクロールします。見える領域。
サードパーティの入力方法に関しては、入力方法パネルがポップアップした後の高さの計算が正しくないため、Web ビューの初期スクロール位置が正しくないと推測されます。実際、これら 2 つの点は、Web ビューが所定の位置にスクロールしないことが原因で発生します。ソフト キーボードがポップアップした後、フォーカス要素を再び表示領域までスクロールして、Web ビューを強制的に所定の位置に移動させることができます。
console.log('Android キーボードがポップアップします!');activeElementScrollIntoView($input, 1000);Android Xiaomi ブラウザと互換性のあるハック ソリューション
Android の Xiaomi ブラウザでは、上記の解決策を適用した後、チャット入力ボックスが依然としてしっかりとブロックされ、scrollIntoView() が動かないままであることがわかりました。つまり、実際にはソフトキーボードが一番下までスクロールされており、ソフトキーボードがポップアップしたときにページの高さがビジュアルエリアの高さよりも大きくなっているためだと思います。このようにすると、ページの高さは後でのみ強制的に増やすことができます。ソフトキーボードがポップアップして入力ボックスが表示されます。上記に基づいて、サードパーティの入力方法と互換性があります。効果を確認するには、ここをクリックしてください。
// Andriod キーボードの格納: Andriod キーボードがポップアップまたは格納されると、ページの高さが変わります。これに基づいて、(judgeDeviceType.isAndroid) { var OriginHeight = document.documentElement.clientHeight || ドキュメントの場合、キーボードの格納がわかります。 body.clientHeight ; window.addEventListener('resize', function () { varsizeHeight = document.documentElement.clientHeight || document.body.clientHeight; if (originHeight < assignHeight) { console.log('Android キーボードが閉じています!'); // Xiaomi ブラウザの入力メソッドによって入力ボックスがブロックされたままになる問題を修正します if (judgeDeviceType.isMiuiBrowser) ) { document.body.style.marginBottom = '0px' } } else { console.log('Android キーボードがポップアップします!'); Xiaomi ブラウザの入力メソッドによって入力ボックスが依然としてブロックされる問題を修正 if (judgeDeviceType.isMiuiBrowser) { document.body.style.marginBottom = '40px' } activeElementScrollIntoView($input, 1000); }、 間違い )}要約する
H5 エンドには長い道のりと落とし穴がたくさんあるので、努力を続ける必要があります。 IOS と Android のソフト キーボード ポップアップ ページのパフォーマンスの違いを理解することが前提条件です。同時に、サードパーティの入力方法と一部のブラウザーの違いを理解して、フォーカス要素を表示領域までスクロールします。を考慮する必要があります。
以上がこの記事の全内容です。皆様の学習のお役に立てれば幸いです。また、VeVb Wulin Network をご支援いただければ幸いです。