1、先新建一个js文件monitorKeyboard.js

/** monitorKeyboard.js
 * @class 监听虚拟键盘
 * @classdesc 监听虚拟键盘弹出隐藏
 * @public onEnd 结束监听虚拟键盘
 * @public onShow 传递一个回调 监听虚拟键盘弹出
 * @public onHidden 传递一个回调 监听虚拟键盘隐藏
 */
 class MonitorKeyboard {
  constructor() {
    this.type = this.IsIA();
    this.originalHeight = document.documentElement.clientHeight || document.body.clientHeight
  }

  /**
   *  @function IsIA 获取设备类型
   *  @param  1 Android 2 iOS
   */
  IsIA = () => {
    const u =  window.navigator.userAgent || "";
    var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
    var isAndroid = u.indexOf("Android") > -1 || u.indexOf("Adr") > -1; //android终端 
    if (isAndroid) {
      return 1;
    } 
    if (isiOS) {
      return 2;
    }
    return 0;
  }

  // Android系统
  onResize = () => {
    //键盘弹起与隐藏都会引起窗口的高度发生变化
    const vHeight = window.visualViewport?.height; 
    const resizeHeight = this.originalHeight - vHeight
    console.log('键盘弹起vHeight',vHeight,'originalHeight',this.originalHeight,'resizeHeight',resizeHeight);
    if (this.originalHeight - resizeHeight > 50) {
      this.show('软键盘弹出');
    } else {
      this.hidden('软键盘收起');
    }
  }

  // iOS获取焦点
  onFocusin = () => {
    this.show('iOS系统:软键盘弹出');
  }

  // iOS失去焦点
  onFocusout = () => {
    this.hidden('iOS系统:软键盘收起');
  }

  /**
   * @function onStart 开始监听虚拟键盘
   */
  onStart = () => { 
    if (this.type == 2) {
      // iOS系统
      window.addEventListener('focusin', this.onFocusin);
      window.addEventListener('focusout', this.onFocusout);
       // 软键盘弹出后切换输入法引起的窗口高度变化,所以IOS系统不能只监听focusin和focusout事件 
        iOS系统直接监听window的resize事件无效,可以监听window.visualViewport
      window.visualViewport?.addEventListener('resize',  this.onResize)
    }else {
      window.addEventListener('resize', this.onResize);
    } 
  }
  /**
   * @function onEnd 结束监听虚拟键盘
   */
  onEnd = () => { 
    if (this.type == 2) {
      window.removeEventListener('focusin', this.onFocusin);
      window.removeEventListener('focusout', this.onFocusout);
       // 软键盘弹出后切换输入法引起的窗口高度变化,所以IOS系统不能只监听focusin和focusout事件 
      window.visualViewport?.removeEventListener('resize',  this.onResize)
    } else {
      window.removeEventListener('resize', this.onResize);
    }
  }

  /**
   * @function  onShow 传递一个回调函数
   * @param  虚拟键盘弹出时触发
   */
  onShow = (fn) => {
    this.show = fn;
  }

  /**
    * @function  onHidden 传递一个回调函数
    * @param  虚拟键盘隐藏时触发
    */
  onHidden = (fn) => {
    this.hidden = fn;
  }
}

export default MonitorKeyboard

2、在组件中引用

import MonitorKeyboard from "@/assets/js/monitorKeyboard.js";

2.1、封装一个方法

   getKeyboardState() {
      this.clientHeight = document.documentElement.clientHeight || document.body.clientHeight
      this.monitorKeyboard = new MonitorKeyboard();
      this.monitorKeyboard.onStart(); 
      // 监听虚拟键盘弹出事件
      this.monitorKeyboard.onShow(() => { 
        setTimeout(() => {
          this.onFocusBlur(true); 
        }, 300); 
      });
      //监听键盘收起的事件
      this.monitorKeyboard.onHidden(() => { 
        this.onFocusBlur(false); 
      });
    },

2.2、在mounted中调用

 mounted() { 
    this.getKeyboardState();
  },

2.3、 在onFocusBlur中处理业务

   onFocusBlur(status){ 
      const vHeight = window.visualViewport?.height ; 
      window.scrollTo(0, this.clientHeight - vHeight);   
    },

月影
2.7k 声望127 粉丝