html5モバイルキーボードのポップアップを片付ける対応
序文:フロントエンドの時間は、プロジェクトの需要も2つのToCモバイルプロジェクトの拡大に基づいて、現在の中間プラットフォームでは、h5モバイルの投げの旅を始めた、以下は、h5モバイルキーボードポップアップでフォームページが離れて互換性のいくつかの要約を置くです。
問題点
h5プロジェクトでは、入力ボックスにフォーカスが当たると自動的にキーボードポップアップが起動するフォームページによく遭遇します。キーボードポップアップはIOSとAndroidのウェブビューで同じように動作せず、また、キーボードタックを積極的に起動する場合にも違いがあります。
キーボードポップアップ
- IOS:IOSのキーボードはウィンドウの上部にあり、キーボードがポップアップされても、Webviewの高さは変わらず、scrollTopだけが変化してページをスクロールすることができます。キーボードがポップアップされ、ページが下にスクロールされた時のみ、scrollTopがキーボードの高さに変化しますが、それ以外の場合は使用できません。このため、IOSの場合、キーボードの本当の高さを知ることは困難である。
- Android:Androidでは、キーボードもウィンドウの上部に表示されます。キーボードがポップアップしたとき、入力ボックスが下部付近にあると、キーボードに遮られ、入力しても視覚的な領域までしかスクロールしません。
キーボードの片付け
- IOSです。キーボードのボタンがトリガーとなってキーボードや入力ボックスの外側のページ領域が引っ込むと、入力ボックスはフォーカスを失うため、入力ボックスのblurイベントがトリガーされます。キーボードが引っ込むと、ページの下部に空白領域が現れ、ページがジャックアップされるようになります。
- Androidです。キーボードのボタンがトリガーされてキーボードが収納されると、入力ボックスはフォーカスを失わないため、ページのblurイベントがトリガーされません。入力ボックスの外側の領域がトリガーされると、入力ボックスはフォーカスを失い、入力ボックスのblurイベントがトリガーされます。
希望する結果
キーボードが飛び出したりしまったりするきっかけとなるシステムの違いに対して、一貫したユーザーエクスペリエンスを維持しながら、できる限りスムーズな機能性を実現したいと考えました。
症状への対応
現在市販されている主な2つのシステムの違いを整理したところで、いよいよ正しいレメディーを入手することにしましょう。
h5にはキーボードイベントを直接聞くインターフェースはありませんが、キーボードのポップアップやピックアップのトリガープロセスやプレゼンテーションを分析することで、キーボードがポップアップされているのかピックアップされているのかを判断することは可能です。
- キーボードのポップアップ。キーボードポップアップは、入力ボックスがフォーカスを得たときに自動的にトリガーされるので、キーボードポップアップの後にフォーカスインイベントをリッスンして、その中に必要なページロジックを実装することが可能です。
-
キーボードを収納した状態 キーボードが他のページ領域に格納されている場合、focusoutイベントをリッスンして、キーボードを格納するために必要なページロジックを実装することができます。キーボードボタンでキーボードをしまう場合、iosとandroidで以下のような違いがあります。
- IOS。フォーカスアウトイベントが発生し、やはりこのメソッドでリッスンします。
- Androidです。フォーカスアウトイベントは発生しません。Androidでは、キーボードの状態切り替え(排出、収納)は入力ボックスと関連するだけでなく、ウェブビューの高さ変化にも影響するため、ウェブビューの高さ変化をリッスンしてキーボードが収納されているかどうかを判断することが可能です。
システム判定
実際には、userAgentを使用して現在のシステムを判断することができます。
const ua = window.navigator.userAgent.toLocaleLowerCase();
const isIOS = /iphone|ipad|ipod/.test(ua);
const isAndroid = /android/.test(ua);
IOS処理
let isReset = true; //whether to return
this.focusinHandler = () => {
isReset = false; //Focus when the keyboard pops up and the focus switches between input boxes, it will first trigger the out-of-focus event of the previous input box, then the focus event of the next input box
};
this.focusoutHandler = () => {
isReset = true;
setTimeout(() => {
// first does not return when focus switches between input boxes in the popup layer
if (isReset) {
window.scroll(0, 0); // make sure the next element is not focused after the delay, it is out of focus caused by putting away the keyboard, then force the page to return
}
}, 30);
};
document.body.addEventListener('focusin', this.focusinHandler);
document.body.addEventListener('focusout', this.focusoutHandler);
Android処理
const originHeight = document.documentElement.clientHeight || document.body.clientHeight;
this.resizeHandler = () => {
const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
const activeElement = document.activeElement;
if (resizeHeight < originHeight) {
// Logic after keyboard pop-up
if (activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA")) {
setTimeout(()=>{
activeElement.scrollIntoView({ block: 'center' });// the focus element rolls to the visible area
},0)
}
} else {
// logic after keyboard is put away
}
};
window.addEventListener('resize', this.resizeHandler);
リアクトラッパー
reactでは、フォームコンポーネントを変更するためのクラスデコレーターを記述することができます。
クラス・デコレーター クラス宣言の前(直後)に宣言します。クラス・デコレータはクラスのコンストラクタに適用され、 クラス定義の監視、変更、置換に使用されます。
// keyboard.tsx
/*
* @Description: Keyboard handling decorator
* @Author: hzzly
* @LastEditors: hzzly
* @Date: 2020-01-09 09:36:40
* @LastEditTime: 2020-01-10 12:08:47
*/
import React, { Component } from 'react';
const keyboard = () => (WrappedComponent: any) =>
class HOC extends Component {
focusinHandler: (() => void) | undefined;
focusoutHandler: (() => void) | undefined;
resizeHandler: (() => void) | undefined;
componentDidMount() {
const ua = window.navigator.userAgent.toLocaleLowerCase();
const isIOS = /iphone|ipad|ipod/.test(ua);
const isAndroid = /android/.test(ua);
if (isIOS) {
// IOS processing above
...
}
if (isAndroid) {
// Android processing above
...
}
}
componentWillUnmount() {
if (this.focusinHandler && this.focusoutHandler) {
document.body.removeEventListener('focusin', this.focusinHandler);
document.body.removeEventListener('focusout', this.focusoutHandler);
}
if (this.resizeHandler) {
document.body.removeEventListener('resize', this.resizeHandler);
}
}
render() {
return <WrappedComponent {. .this.props} />;
}
};
export default keyboard;
を使用します。
// PersonForm.tsx
@keyboard()
class PersonForm extends PureComponent<{}, {}> {
// Business logic
...
}
export default PersonForm;
以上が今回の記事の内容です。皆様の学習のお役に立てれば幸いです。また、スクリプトハウスを応援していただければ幸いです。
関連
-
Html5+CSS3+EL表現問題まとめ
-
ログイン期限切れでIframフレームワークから飛び出す方法を説明する
-
HTML5でオプションのスタイルシートを使ってWebサイトやアプリケーションにダークモードを追加する方法を解説
-
高解像度画面でのキャンバスブラーの問題を記憶する
-
Html5ポジショニングの究極のソリューション
-
textareaで改行や空白を処理する
-
VSCodeカスタムhtml5テンプレート実装
-
HTML5によるアプリケーションキャッシュの実装
-
HTML表示 pdf, word, xls, ppt方式例
-
N種類のキャンバスエクスポートイメージのクロスドメインポーズサマリーのロックを解除する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
HTML5 回転画像フルコード
-
window.postMessage を用いた html5 のクロスドメインデータインタラクション
-
キャンバステキストフィルリニアグラデーション使用詳細説明
-
Html5ナビゲーションバー天井画の原理と対照的な実装
-
recorder.js Html5ベースの録画機能実装
-
H5 オフラインストレージ マニフェストの原理と使い方
-
html2canvasのスクリーンショットが空白になる問題の解決法
-
AmazeUIのダウンロード設定とHelloworldの実装について
-
IOSキーボードがfocusoutイベントでしまわれたときに元の場所に戻らない問題を解決する
-
キャンバス画像getImageData,toDataURLのクロスドメイン問題の解決方法を説明する。