解决H5在native中键盘弹起影响页面交互

news2024/11/24 1:23:39

您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~

问题描述

native中拉起键盘再收回,滚动列表实际距离发生变化,被键盘一起弹上去了(我这里大约是400px的样子)

这是初始页面:

在这里插入图片描述

当我聚焦页面中某个Input后,再失去焦点,页面变成了这样:

在这里插入图片描述

可以看到页面被弹上去了,再次重复步骤页面会继续弹上去,排查了一下发现是在IOS中的问题。

解决方案

我这里想到的一个比较好的方案是监听弹起键盘收起键盘两个事件,在弹起时记录被破坏的页面scrollY,收起时恢复。

记录弹起时的页面scrollY挺简单的,直接这样:

window.addEventListener('focusin', () => {
    console.log('弹起前高度:', window.scrollY);
}, false)

这样思路就很简单了,代码实现一下:

const focusScrollHeight = useRef<number>(0);

  useEffect(() => {
    window.addEventListener('focusin', focusIn, false);
    window.addEventListener('focusout', focusOut, false);
    return () => {
      window.removeEventListener('focusin', focusIn, false);
      window.removeEventListener('focusout', focusOut, false);
    };
  }, []);

  const focusIn = () => {
    focusScrollHeight.current = window.scrollY;
  };

  const focusOut = (e) => {
    window.scrollTo(0, focusScrollHeight.current);
  };

把这段代码放在出现问题的页面里,发现页面会不稳定的回弹到顶部,排查下来应该是antd的组件触发了收起键盘的事件,所以考虑用类名定位的方案来搞定,同时我们直接封装成一个hook,在出现问题的页面中直接使用,就像这样:

useResetScrollY.ts

/**
 * @description: 声明式hook,在页面声明即可自动归位手机端键盘弹起撑开的高度
 * @param {string} listenerClassList 监听的类名
 * @return {*}
 */
const useResetScrollY = (listenerClassList: string[]) => {
  const focusScrollHeight = useRef<number>(0);

  useEffect(() => {
    window.addEventListener('focusin', focusIn, false);
    window.addEventListener('focusout', focusOut, false);
    return () => {
      window.removeEventListener('focusin', focusIn, false);
      window.removeEventListener('focusout', focusOut, false);
    };
  }, []);

  const focusIn = () => {
    focusScrollHeight.current = window.scrollY;
  };

  const focusOut = (e) => {
    const classNameList: string[] = Array.from(e?.target?.classList);
    if (classNameList?.some((item: string) => listenerClassList?.includes(item))) {
      window.scrollTo(0, focusScrollHeight.current);
    }
  };
};

export { useResetScrollY };

这里入参我们给出在页面中需要被监听的组件类名,一般来说都是InputTextarea这类表单组件,然后在这个页面我使用的是antdInput组件,所以使用是这样的:

const Page = () => {
    // ...
    
    if(isIos) {
        useResetScrollY(['adm-input-element']);
    }
    // ...
}

这样子在hook内部触发事件时只需要判断事件对象的classList与入参classList是否存在公共项的情况,就会触发键盘副作用归位的行为。

写在后面

这是笔者在业务中遇到的一个问题,简单总结记录,如果对于这种情况有更好的方案也欢迎留言讨论~

您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/652517.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用yolox训练自己的数据集并测试

1.首先给出yolox原模型的下载地址: ​​​​​​https://github.com/bubbliiiing/yolox-pytorch 百度网盘链接给出自己完整的模型&#xff08;包括数据集以及权重文件&#xff09;&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1JNjB42u9eGNhRjr1SfD_Tw 提取码&am…

Redis和Redis可视化管理工具的下载和安装

文章目录 Redis 简介一&#xff0c;Redis 下载二&#xff0c;Redis 安装三&#xff0c;Redis 配置四&#xff0c;Redis 启动 Redis-Desktop-Manager 简介一&#xff0c;Redis-Desktop-Manager 下载二&#xff0c;Redis-Desktop-Manager 安装三&#xff0c;Redis-Desktop-Manage…

深度学习笔记之Transformer(三)自注意力机制

深度学习笔记之Transformer——自注意力机制 引言回顾&#xff1a;缩放点积注意力机制自注意力机制自注意力机制与 RNN,CNN \text{RNN,CNN} RNN,CNN的对比简单介绍&#xff1a;卷积神经网络处理序列信息的原理从计算复杂度的角度观察 位置编码 引言 上一节对注意力分数 ( Atte…

关于前端Vue脚手架的完整搭建

创建脚手架 在VSC中打开命令行&#xff0c;输入如下命令可以用于创建脚手架 Vue create <项目名称>会出现如下选项&#xff1a; 前面是选项的名称&#xff0c;括号中的是选项包含有&#xff1a; 1、Vue的版本 2、babel是用于将高版本的js转化成为低版本的js&#xff0…

SSM 整合案例

Ssm整合 注意事项 Spring mvcSpringMybatisMySQL项目结构&#xff0c;以web项目结构整合&#xff08;还有maven、gradle&#xff09;整合日志、事务一个项目中Idea 2019、JDK12、Tomcat9、MySQL 5.5 项目结构 D:\java\Idea\Idea_spacework\SSMhzy&#xff1a;不会就去找项目…

chatgpt赋能python:Python怎么筛选奇数

Python怎么筛选奇数 Python是一种高级编程语言&#xff0c;既具有面向对象编程的特点&#xff0c;又可以进行函数式编程。Python的语法简洁、清晰&#xff0c;非常适合初学者学习。在Python中&#xff0c;筛选奇数的方法非常简单&#xff0c;本文将介绍Python中筛选奇数的方法…

人机交互学习-5 交互式系统的需求

交互式系统的需求 需求是什么需求需求活动 产品特性用户特性体验水平差异新手用户专家用户中间用户 年龄差异老年人儿童 文化差异健康差异 用户建模人物角色人物角色的作用人物角色的构造错误观点人物角色基于问题举例注意事项 建模过程 需求获取、分析和验证观察场景人物角色场…

爬虫数据是如何收集和整理的?

爬虫数据的收集和整理通常包括以下步骤&#xff1a; 确定数据需求&#xff1a;确定要收集的信息类型、来源和范围。 网络爬取&#xff1a;使用编程工具&#xff08;如Python的Scrapy、BeautifulSoup等&#xff09;编写爬虫程序&#xff0c;通过HTTP请求获取网页内容&#xff…

网卡命名规则和网卡变动结论

net.ifnames0 biosdevname0 插卡前状态&#xff1a; 插卡后状态&#xff1a; 结论&#xff1a;明显eth0 MAC地址从00:0d:48:94:10:fc 变更为 c0:33:da:10:31:ff。该方法eth0实际对应的网口发生了变动。 net.ifname1 插卡前状态&#xff1a; 插卡后状态&#xff1a; 查看…

MEC | 条款2 最好使用C++转型操作符

条款2 最好使用C转型操作符 文章目录 条款2 最好使用C转型操作符c4个转型操作符static_castconst_castdynamic_castreinterpret_cast 宏模仿新转换语法欢迎关注公众号【三戒纪元】 c4个转型操作符 static_castconst_castdynamic_castreinterpret_cast 原因是 新式转型方法容…

chatgpt赋能python:Python在SEO中如何确定主语?

Python在SEO中如何确定主语&#xff1f; Python是一种高级编程语言&#xff0c;广泛应用于Web开发、数据分析和机器学习等领域。但是&#xff0c;Python编写的网页是否符合SEO标准&#xff0c;是一个需要重视的问题。在SEO中&#xff0c;主语是一个非常重要的因素。那么&#…

CLickhouse 物化视图--干货记录(亲验证)

1、普通视图VS物化视图 普通视图不保存数据&#xff0c;保存的仅仅是查询语句&#xff0c;查询的时候还是从原表读取数据&#xff0c;可以将普通视图理解为是个子查询。--中看不中用 物化视图则是把查询的结果根据相应的引擎存入到了磁盘或内存中&#xff0c;对数据重新进行了…

Duilib中禁止一个窗口双击最大化

1、Duilib中禁止一个窗口双击最大化 用duilib开发了一个窗口&#xff0c;比如是登录窗口&#xff0c;那么这个窗口的窗口的双击最大化就毫无意义&#xff0c;甚至带来灾难&#xff0c;我们就要明确禁止这样的行为。 我们应该明确&#xff0c;一个窗口创建的时候就赋予了它一些…

内核链表、JSON的序列化与反序列化

1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除&#xff1b; 2) 结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍&#xff0c;如有需要编译器会在成员之间加上填充字节(internal adding)&#xff1b; 3) 结构体的总大小为结构体最宽基本类型…

计算机组成原理(考研408)练习题#3

用于复习408或计算机组成原理期末考试。如有错误请在评论区指出。 So lets start studying with questions! それでは、問題の勉強を始めましょう&#xff01; 1. 定点整数原码编码[x]原1110100B 的真值为_________。 首先&#xff0c;1110100B是一个8位二进制数&#xff0c…

Spring Cloud Sleuth使用简介

Spring-Cloud Spring Cloud为开发者提供了在分布式系统(如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性Token、全局锁、决策竞选、分布式会话和集群状态)操作的开发工具。使用SpringCloud开发者可以快速实现上述这些模式。 SpringCloud Sleuth Distribu…

【0基础教程】Javascript 正则表达式里的分组捕捉 Capturing Groups 使用方法及原理

一、从最简单开始 现有一个字符串&#xff1a; “1-apple” 需要解析出 1 和 apple 来&#xff0c;对应的正则表达式很简单&#xff1a; ^(\d)-(.)$ 其中&#xff0c; ^ 表示字符串的开始&#xff0c;然后一个圆括号包裹的内容表示一个"组"&#xff1a;(\d) 表示一组…

【深度学习】2-1 神经网络 - 激活函数

激活函数 将输入信号的总和转换为输出信号&#xff0c;一般称为激活函数&#xff08;activation function&#xff09;。激活函数作用在于决定如何来激活输入信号的总和。 对激活函数&#xff0c;一般要求&#xff1a; 非线性&#xff1a;为提高模型的学习能力&#xff0c;如…

Nginx reuseport导致偶发性卡顿

背景 从2018年开始&#xff0c;我们有个业务陆续接到反馈 Nginx 线上集群经常出现不响应或者偶发性的“超慢”请求。这种卡顿每天都有少量出现。而只有多个集群中的一个出现&#xff0c;其他压力更大的集群皆未出现。 业务结构比较简单&#xff1a;LVS->Nginx->后端&…

Advanced-C.01.基础知识

C语言程序设计概述 一个简单句的C程序 #include <stdio.h> int main(){printf("This is a C program.\n");retrun 0; }C程序的执行过程 数据单位 bit&#xff1a;位&#xff0c;计算机中最小的数据单位Byte&#xff1a;字节&#xff0c;计算机中信息组织和存…