H5 (React) 移动端监听软键盘弹起、收起

前言:H5 有时底部按钮是固定定位,当页面上面需要用到输入内容时,会弹起软键盘,然后把底部固定的按钮也弹起来了,我们希望弹起软键盘时,底部的固定定位按钮隐藏,这里就需要对移动端软键盘弹起收起进行监听。

1. Android端

  // 控制整个按钮底部的显示与隐藏
  const [hideBottom, setHideBottom] = useState<boolean>(false);

  useEffect(() => {
    
    
    // 原窗口高度 
    const originalHeight = document.documentElement.clientHeight || document.body.clientHeight;
    window.addEventListener('resize', () => {
    
    
      //键盘弹起与隐藏都会引起窗口的高度发生变化
      const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
      if (resizeHeight - 0 < originalHeight - 0) {
    
    
        //当软键盘弹起,在此处操作
        setHideBottom(true);
      } else {
    
    
        //当软键盘收起,在此处操作
        setHideBottom(false);
      }
    });
  }, []);
OR
  // 控制整个按钮底部的显示与隐藏
const [hideBottom, setHideBottom] = useState<boolean>(false);

useEffect(() => {
    
    
  // 原窗口高度
  const originalHeight = document.documentElement.clientHeight || document.body.clientHeight;
  window.onresize = () => {
    
    
    //键盘弹起与隐藏都会引起窗口的高度发生变化
    const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
    if (resizeHeight - 0 < originalHeight - 0) {
    
    
      //当软键盘弹起,在此处操作
      setHideBottom(true);
    } else {
    
    
      //当软键盘收起,在此处操作
      setHideBottom(false);
    }
  };
}, []);

2. IOS端

  // 控制整个按钮底部的显示与隐藏
  const [hideBottom, setHideBottom] = useState<boolean>(false);

  useEffect(() => {
    
    
    document.body.addEventListener('focusin', () => {
    
    
      //软键盘弹出的事件处理
      setHideBottom(true);
    });
    document.body.addEventListener('focusout', () => {
    
    
      //软键盘收起的事件处理
      setHideBottom(false);
    });
  }, []);

3. 融合终极办法

// utils.ts
export const monitorSoftKeyboard = callback => {
    
    
  // 1. Android系统
  const originalHeight = document.documentElement.clientHeight || document.body.clientHeight;
  window.addEventListener('resize', () => {
    
    
    //键盘弹起与隐藏都会引起窗口的高度发生变化
    const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
    if (resizeHeight - 0 < originalHeight - 0) {
    
    
      //当软键盘弹起,在此处操作
      callback(true);
    } else {
    
    
      //当软键盘收起,在此处操作
      callback(false);
    }
  });
  // 2. IOS系统(兼容)
  document.body.addEventListener('focusin', () => {
    
    
    //软键盘弹出的事件处理
    callback(true);
  });
  document.body.addEventListener('focusout', () => {
    
    
    //软键盘收起的事件处理
    callback(false);
  });
};

// page
// 控制整个按钮底部的显示与隐藏
const [hideBottom, setHideBottom] = useState<boolean>(false);
 
useEffect(() => {
    
    
 monitorSoftKeyboard(isUp => {
    
    
   if (isUp) {
    
    
     setHideBottom(true);
   } else {
    
    
     setHideBottom(false);
   }
 });
}, []);

解释

  1. 在android中软键盘弹起或收起时,会改变window的高度,因此监听window的onresize事件;但是 ios 中软键盘的弹起收起并不触发 window.onresize 事件;
  2. 在 ios 中软键盘弹起时,仅会引起 scrollTop 值改变,但是我们可以通过输入框的获取焦点情况来做判断,但也只能在 ios 中采用这个方案,因为在 android 中存在主动收起键盘后,但输入框并没有失焦,而ios中键盘收起后就会失焦
  3. 另外,focusin和focusout支持冒泡,对应focus和blur, 使用focusin和focusout的原因是focusin和focusout可以冒泡,focus和blur不会冒泡,这样就可以使用事件代理,处理多个输入框存在的情况。

猜你喜欢

转载自blog.csdn.net/yiguoxiaohai/article/details/125872156