最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

html5手機(jī)鍵盤(pán)彈出收起的處理

  發(fā)布時(shí)間:2020-01-20 16:06:38   作者:hzzly   我要評(píng)論
這篇文章主要介紹了html5手機(jī)鍵盤(pán)彈出收起的處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言:前端時(shí)間也是應(yīng)項(xiàng)目的需求開(kāi)始了h5移動(dòng)端的折騰之旅,在目前中臺(tái)的基礎(chǔ)上擴(kuò)展了兩個(gè)ToC移動(dòng)端項(xiàng)目,下面就是在h5移動(dòng)端表單頁(yè)面鍵盤(pán)彈出收起兼容性的一些總結(jié)。

問(wèn)題

在 h5 項(xiàng)目中,我們會(huì)經(jīng)常遇到一些表單頁(yè)面,在輸入框獲取焦點(diǎn)時(shí),會(huì)自動(dòng)觸發(fā)鍵盤(pán)彈起,而鍵盤(pán)彈出在 IOS 與 Android 的 webview 中表現(xiàn)并非一致,同時(shí)當(dāng)我們主動(dòng)觸發(fā)鍵盤(pán)收起時(shí)也同樣存在差異化。

鍵盤(pán)彈出

  • IOS:IOS系統(tǒng) 的鍵盤(pán)處在窗口的最上層,當(dāng)鍵盤(pán)彈起時(shí),webview 的高度 height 并沒(méi)有改變,只是 scrollTop 發(fā)生變化,頁(yè)面可以滾動(dòng)。且頁(yè)面可以滾動(dòng)的最大限度為彈出的鍵盤(pán)的高度,而只有鍵盤(pán)彈出時(shí)頁(yè)面恰好也滾動(dòng)到最底部時(shí),scrollTop 的變化值為鍵盤(pán)的高度,其他情況下則無(wú)法獲取。這就導(dǎo)致在 IOS 情況下難以獲取鍵盤(pán)的真實(shí)高度。
  • Android: 在Android系統(tǒng)中,鍵盤(pán)也是處在窗口的最上層,鍵盤(pán)彈起時(shí),如果輸入框在靠近底部的話,就會(huì)被鍵盤(pán)擋住,只有你輸入的時(shí)候輸入框才會(huì)滾動(dòng)到可視化區(qū)域。

鍵盤(pán)收起

  • IOS:觸發(fā)鍵盤(pán)上的按鈕收起鍵盤(pán)或者輸入框以外的頁(yè)面區(qū)域時(shí),輸入框會(huì)失去焦點(diǎn),因此會(huì)觸發(fā)輸入框的 blur 事件;當(dāng)鍵盤(pán)收起時(shí),頁(yè)面底部會(huì)出現(xiàn)一個(gè)空白區(qū)域,頁(yè)面會(huì)被頂起。
  • Android: 觸發(fā)鍵盤(pán)上的按鈕收起鍵盤(pán)時(shí),輸入框并不會(huì)失去焦點(diǎn),因此不會(huì)觸發(fā)頁(yè)面的 blur 事件;觸發(fā)輸入框以外的區(qū)域時(shí),輸入框會(huì)失去焦點(diǎn),觸發(fā)輸入框的 blur 事件。

期望的結(jié)果

針對(duì)不同系統(tǒng)觸發(fā)鍵盤(pán)彈出收起時(shí)的差異化,我們希望功能流暢的同時(shí),盡量保持用戶(hù)體驗(yàn)的一致性。

對(duì)癥下藥

上面我們理清了目前市面上兩大主要系統(tǒng)的差異性,接下來(lái)就需對(duì)癥下藥了。

在 h5 中目前沒(méi)有接口可以直接監(jiān)聽(tīng)鍵盤(pán)事件,但我們可以通過(guò)分析鍵盤(pán)彈出、收起的觸發(fā)過(guò)程及表現(xiàn)形式,來(lái)判斷鍵盤(pán)是彈出還是收起的狀態(tài)。

  • 鍵盤(pán)彈出:輸入框獲取焦點(diǎn)時(shí)會(huì)自動(dòng)觸發(fā)鍵盤(pán)的彈起動(dòng)作,因此,我們可以監(jiān)聽(tīng) focusin 事件,在里面實(shí)現(xiàn)鍵盤(pán)彈出后所需的頁(yè)面邏輯。
  • 鍵盤(pán)收起:當(dāng)觸發(fā)其他頁(yè)面區(qū)域收起鍵盤(pán)時(shí),我們可以監(jiān)聽(tīng) focusout 事件,在里面實(shí)現(xiàn)鍵盤(pán)收起后所需的頁(yè)面邏輯。而在通過(guò)鍵盤(pán)按鈕收起鍵盤(pán)時(shí)在 ios 與 android 端存在差異化表現(xiàn),下面具體分析:
    • IOS:觸發(fā)了 focusout 事件,仍然通過(guò)該辦法監(jiān)聽(tīng)。
    • Android:沒(méi)有觸發(fā) focusout 事件。在 android 中,鍵盤(pán)的狀態(tài)切換(彈出、收起)不僅和輸入框關(guān)聯(lián),同時(shí)還會(huì)影響到 webview 高度的變化,那我們就可以通過(guò)監(jiān)聽(tīng) webview height 的變化來(lái)判斷鍵盤(pán)是否收起。

系統(tǒng)判斷

在實(shí)踐中我們可以通過(guò) userAgent 來(lái)判斷目前的系統(tǒng):

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; //聚焦時(shí)鍵盤(pán)彈出,焦點(diǎn)在輸入框之間切換時(shí),會(huì)先觸發(fā)上一個(gè)輸入框的失焦事件,再觸發(fā)下一個(gè)輸入框的聚焦事件
};

this.focusoutHandler = () => {
  isReset = true;
  setTimeout(() => {
    //當(dāng)焦點(diǎn)在彈出層的輸入框之間切換時(shí)先不歸位
    if (isReset) {
        window.scroll(0, 0); //確定延時(shí)后沒(méi)有聚焦下一元素,是由收起鍵盤(pán)引起的失焦,則強(qiáng)制讓頁(yè)面歸位
    }
  }, 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) {
    // 鍵盤(pán)彈起后邏輯
    if (activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA")) {
      setTimeout(()=>{
        activeElement.scrollIntoView({ block: 'center' });//焦點(diǎn)元素滾到可視區(qū)域的問(wèn)題
      },0)
    }
  } else {
    // 鍵盤(pán)收起后邏輯
  }
};

window.addEventListener('resize', this.resizeHandler);

react 封裝

在 react 中我們可以寫(xiě)一個(gè)類(lèi)裝飾器來(lái)修飾表單組件。

類(lèi)裝飾器:類(lèi)裝飾器在類(lèi)聲明之前被聲明(緊靠著類(lèi)聲明)。 類(lèi)裝飾器應(yīng)用于類(lèi)構(gòu)造函數(shù),可以用來(lái)監(jiān)視,修改或替換類(lèi)定義。

// keyboard.tsx
/*
 * @Description: 鍵盤(pán)處理裝飾器
 * @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<{}, {}> {
  // 業(yè)務(wù)邏輯
  ...
}

export default PersonForm;

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

石景山区| 高邑县| 隆昌县| 常宁市| 柳河县| 定安县| 宜川县| 古交市| 铁岭市| 仪陇县| 格尔木市| 嵊泗县| 沐川县| 修文县| 贵南县| 琼中| 濮阳市| 景东| 阜南县| 巴彦县| 抚顺市| 金秀| 太保市| 西贡区| 邮箱| 岚皋县| 成都市| 洛宁县| 铁岭县| 克拉玛依市| 南和县| 六枝特区| 红安县| 平江县| 长寿区| 南通市| 甘南县| 江津市| 镇赉县| 邻水| 大同市|