国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > HTML5 > 正文

html5手機鍵盤彈出收起的處理

2024-09-05 07:23:15
字體:
來源:轉載
供稿:網友

前言:前端時間也是應項目的需求開始了h5移動端的折騰之旅,在目前中臺的基礎上擴展了兩個ToC移動端項目,下面就是在h5移動端表單頁面鍵盤彈出收起兼容性的一些總結。

問題

在 h5 項目中,我們會經常遇到一些表單頁面,在輸入框獲取焦點時,會自動觸發鍵盤彈起,而鍵盤彈出在 IOS 與 Android 的 webview 中表現并非一致,同時當我們主動觸發鍵盤收起時也同樣存在差異化。

鍵盤彈出

  • IOS:IOS系統 的鍵盤處在窗口的最上層,當鍵盤彈起時,webview 的高度 height 并沒有改變,只是 scrollTop 發生變化,頁面可以滾動。且頁面可以滾動的最大限度為彈出的鍵盤的高度,而只有鍵盤彈出時頁面恰好也滾動到最底部時,scrollTop 的變化值為鍵盤的高度,其他情況下則無法獲取。這就導致在 IOS 情況下難以獲取鍵盤的真實高度。
  • Android: 在Android系統中,鍵盤也是處在窗口的最上層,鍵盤彈起時,如果輸入框在靠近底部的話,就會被鍵盤擋住,只有你輸入的時候輸入框才會滾動到可視化區域。

鍵盤收起

  • IOS:觸發鍵盤上的按鈕收起鍵盤或者輸入框以外的頁面區域時,輸入框會失去焦點,因此會觸發輸入框的 blur 事件;當鍵盤收起時,頁面底部會出現一個空白區域,頁面會被頂起。
  • Android: 觸發鍵盤上的按鈕收起鍵盤時,輸入框并不會失去焦點,因此不會觸發頁面的 blur 事件;觸發輸入框以外的區域時,輸入框會失去焦點,觸發輸入框的 blur 事件。

期望的結果

針對不同系統觸發鍵盤彈出收起時的差異化,我們希望功能流暢的同時,盡量保持用戶體驗的一致性。

對癥下藥

上面我們理清了目前市面上兩大主要系統的差異性,接下來就需對癥下藥了。

在 h5 中目前沒有接口可以直接監聽鍵盤事件,但我們可以通過分析鍵盤彈出、收起的觸發過程及表現形式,來判斷鍵盤是彈出還是收起的狀態。

  • 鍵盤彈出:輸入框獲取焦點時會自動觸發鍵盤的彈起動作,因此,我們可以監聽 focusin 事件,在里面實現鍵盤彈出后所需的頁面邏輯。
  • 鍵盤收起:當觸發其他頁面區域收起鍵盤時,我們可以監聽 focusout 事件,在里面實現鍵盤收起后所需的頁面邏輯。而在通過鍵盤按鈕收起鍵盤時在 ios 與 android 端存在差異化表現,下面具體分析:
    • IOS:觸發了 focusout 事件,仍然通過該辦法監聽。
    • Android:沒有觸發 focusout 事件。在 android 中,鍵盤的狀態切換(彈出、收起)不僅和輸入框關聯,同時還會影響到 webview 高度的變化,那我們就可以通過監聽 webview height 的變化來判斷鍵盤是否收起。

系統判斷

在實踐中我們可以通過 userAgent 來判斷目前的系統:

const ua = window.navigator.userAgent.toLocaleLowerCase();const isIOS = /iphone|ipad|ipod/.test(ua);const isAndroid = /android/.test(ua);

IOS 處理

let isReset = true; //是否歸位this.focusinHandler = () => {  isReset = false; //聚焦時鍵盤彈出,焦點在輸入框之間切換時,會先觸發上一個輸入框的失焦事件,再觸發下一個輸入框的聚焦事件};this.focusoutHandler = () => {  isReset = true;  setTimeout(() => {    //當焦點在彈出層的輸入框之間切換時先不歸位    if (isReset) {        window.scroll(0, 0); //確定延時后沒有聚焦下一元素,是由收起鍵盤引起的失焦,則強制讓頁面歸位    }  }, 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) {    // 鍵盤彈起后邏輯    if (activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA")) {      setTimeout(()=>{        activeElement.scrollIntoView({ block: 'center' });//焦點元素滾到可視區域的問題      },0)    }  } else {    // 鍵盤收起后邏輯  }};window.addEventListener('resize', this.resizeHandler);

react 封裝

在 react 中我們可以寫一個類裝飾器來修飾表單組件。

類裝飾器:類裝飾器在類聲明之前被聲明(緊靠著類聲明)。 類裝飾器應用于類構造函數,可以用來監視,修改或替換類定義。

// keyboard.tsx/* * @Description: 鍵盤處理裝飾器 * @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 處理        ...      }      if (isAndroid) {        // 上面 Android 處理        ...      }    }    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<{}, {}> {  // 業務邏輯  ...}export default PersonForm;

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 高平市| 东明县| 山丹县| 桐庐县| 千阳县| 乳山市| 扬中市| 荆州市| 刚察县| 凤城市| 酉阳| 白山市| 罗田县| 宜黄县| 济阳县| 宝应县| 通榆县| 临夏市| 白朗县| 金川县| 攀枝花市| 南溪县| 高青县| 昌宁县| 罗城| 绍兴县| 格尔木市| 集贤县| 江门市| 淳安县| 龙江县| 房山区| 宁夏| 青河县| 道孚县| 呼伦贝尔市| 策勒县| 武乡县| 通城县| 金阳县| 荥经县|