1. ホーム
  2. Web制作
  3. html5

html5モバイルキーボードのポップアップを片付ける対応

2022-01-27 04:26:14

序文:フロントエンドの時間は、プロジェクトの需要も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;



以上が今回の記事の内容です。皆様の学習のお役に立てれば幸いです。また、スクリプトハウスを応援していただければ幸いです。