IOS输入框聚焦会把内容区域顶起

前几天做了一个类似qq布局的h5的聊天界面,输入框固定在最底下。本来初始情况会有默认的两条聊天记录,但是当点击底部的输入框时,输入框聚焦,弹起键盘,然后整个界面就被顶上去了,然后那两条默认的聊天记录也被顶上去了,导致整个页面没内容了。

这里给出一个demo(如果样式有问题,请将浏览器的模拟器调到iphone 6/7/8)

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport"content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no,viewport-fit=cover" /><title>Document</title><style>* {margin: 0;padding: 0;}html,body {width: 100%;height: 100%;overflow: hidden;background-color: pink;}p {margin-bottom: 1.875rem;}.left {text-align: left;}.right {text-align: right;color: blue;}.chatContainer {height: 100%;overflow: auto;}.inputBox {display: flex;position: fixed;bottom: 0;left: 0;right: 0;height: 1.875rem;z-index: 999;}input {flex: 1;margin-right: .5rem;}button {width: 6.25rem;height: 100%;}</style>
</head><body><div class="chatContainer"><div class="flag"></div><div class="chat"><p class="left">你好,我是XXX,一个机器人</p><p class="left">请问您需要问什么</p></div></div><div class="inputBox"><input type="text" /><button>发送</button></div><script>let oBtn = document.querySelector('button')let oChatContainer = document.querySelector('.chatContainer')let oInput = document.querySelector('input')let oFlag = document.querySelector('.flag')oBtn.onclick = () => {let inputValue = oInput.valueif (!inputValue) returnlet oDiv1 = document.createElement('p')let oDiv2 = document.createElement('p')oDiv1.className = 'right'oDiv1.innerText = inputValueoDiv2.className = 'left'oDiv2.innerText = '感谢您的回复!'oChatContainer.appendChild(oDiv1)oChatContainer.appendChild(oDiv2)oDiv2.scrollIntoView({behavior: "smooth"})oInput.value = ''}</script>
</body></html>

感觉这个好像并没有什么问题,安卓可以正常的显示,交互。但是IOS就是不行,并且我还设置了

  .inputBox {display: flex;bottom: 0;z-index: 999;}

让我百思不得其解,,最后发现这是IOS手机的通病,没办法,只能进行hack了。

我的最终解决思路是,既然聚焦会定顶起内容区域,那么顶起来多少,我就用空白的元素占位多少高度,这样内容就显示出来了。当手指在屏幕滑动时,再把占位块高度变为0。如果内容区域的高度大于了被顶起的高度(或者内容区域的高度多出了被顶起的高度20px之类的),那么就不需要占位了,因为这个时候肯定有内容区域的元素露出来了。

最终的js代码如下

insetPlaceholder(oChatContainer, oInput)
function insetPlaceholder(containerEl, inputEl) {// 只有苹果手机会导致输入框聚焦顶底整个内容区域,所有这个函数只对IOS系统进行兼容处理let isIos = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);if (!isIos) return/*** 这里这个是一个死的元素结构* 类似这样*  <div class="container"><div class="flag"></div><div class="content"></div></div>*  container是整体,flag是占位元素,根据情况切换高度*  content是实际的内容区域*/let oFlag = containerEl.children[0]let oContent = containerEl.children[1]let containerElTouchstartIsRemove = false/*** 记录第一次聚焦的时候,container这个大盒子究竟被顶起来多少,把这个值记录为flag的高度* 以后每次聚焦都会和这个值做比较,如果content的高度大于了顶起来的高度,那么说明内容已经足够多了,所以就不需要flag来占位了,然后把 flagEl 高度设置为0*/let isFirstFocusFlagElHeight = undefinedconst onInputFocus = () => {isFirstFocusFlagElHeight === undefined && (isFirstFocusFlagElHeight = Math.abs(oFlag.getBoundingClientRect().top))let insetPlaceholderHeight = isFirstFocusFlagElHeight - oContent.offsetHeightif (insetPlaceholderHeight > 0) {setTimeout(() => {oFlag.style.height = insetPlaceholderHeight}, 3e2)} else {if (!containerElTouchstartIsRemove) {containerEl.removeEventListener('touchstart', onContainerElTouchstart)containerElTouchstartIsRemove = true}}}oInput.addEventListener('focus', onInputFocus)/*** 监听这个事件主要是为了隐藏那个占位元素* 防止用户滑动界面把占位元素露出来* 并且很奇怪,如果不这样做,输入框会滚动!并且我已经设置了固定定位!* 如果占位元素没有了,那就可以把这个事件移除了* */const onContainerElTouchstart = () => {if (oFlag.style.height > 0) {oFlag.style.height = 0oInput.blur()}}containerEl.addEventListener('touchstart', onContainerElTouchstart)
}

或者如果你的初始内容足够多,那你也不需要考虑这个问题

这里需要注意的时我的insetPlaceholder方法时需要一个特定的html结构的,需要这样的结构

<div class="container"><div class="flag"></div><div class="content"></div>
</div>

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

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

相关文章

gitlab环境准备

1.准备环境 gitlab只支持linux系统&#xff0c;本人在虚拟机下使用Ubuntu作为操作系统&#xff0c;gitlab镜像要使用和操作系统版本对应的版本&#xff0c;(ubuntu18.04,gitlab-ce_13.2.3-ce.0_amd64 .deb) book100ask:/$ lsb_release -a No LSB modules are available. Dist…

机器学习二元分类 二元交叉熵 二元分类例子

二元交叉熵损失函数 深度学习中的二元分类损失函数通常采用二元交叉熵&#xff08;Binary Cross-Entropy&#xff09;作为损失函数。 二元交叉熵损失函数的基本公式是&#xff1a; L(y, y_pred) -y * log(y_pred) - (1 - y) * log(1 - y_pred)其中&#xff0c;y是真实标签&…

【C++11】右值引用使用详解

系列文章目录 C11新特性使用详解-持续更新 文章目录 系列文章目录前言一、关联特性1.1 左值/右值 二、使用方法2.1 获得右值引用2.2 对象移动方法2.2.1 移动构造函数/移动赋值运算符2.2.2 标记为noexcept2.2.3 使移动源对象进入是可析构状态 三、使用场景3.1 移动语义3.1 完美…

中贝通信-603220 三季报分析(20231120)

中贝通信-603220 基本情况 公司名称&#xff1a;中贝通信集团股份有限公司 A股简称&#xff1a;中贝通信 成立日期&#xff1a;1999-12-29 上市日期&#xff1a;2018-11-15 所属行业&#xff1a;软件和信息技术服务业 周期性&#xff1a;1 主营业务&#xff1a;通信网络技术服务…

Qt ListWidget

先创建QListWidgetItem&#xff1a; QListWidgetItem* pListItem1 new QListWidgetItem(QIcon(":/resources/editor.png"),u8"editor");QListWidgetItem* pListItem2 new QListWidgetItem(QIcon(":/resources/env.png"),u8"env");Q…

通信网络安全防护定级备案流程介绍(附流程图)

通信网络安全防护定级备案是拥有增值电信业务经营许可证并且有开展电信业务的企业要做的一件事情。刚接触这块的家人们在填报操作的时候可能对具体通信网络安全防护定级备案流程还不是很清楚&#xff0c;所以就给大家画张具体的流程图吧&#xff0c;可以更加直观的了解。 通信…

go语言学习-go环境安装

1、安装Go 1.1 下载安装 go官网 找对应电脑的版本进行安装即可。 点击安装包&#xff0c;直接下一步下一步即可&#xff0c;安装目录可以自行设置一下。 1.2 验证 windows通过cmd验证。 linux或者mac可以通过自带终端执行测试。 2、配置环境变量 2.1 windows 找到系统…

HarmonyOS开发(四):UIAbility组件

1、UIAbility概述 UIAbility 一种包含用户界面的应用组件用于与用户进行交互系统调度的单元为应用提供窗口在其中绘制界同 注&#xff1a;每一个UIAbility实例&#xff0c;都对应一个最近任务列表中的任务。 一个应用可以有一个UIAbility也可以有多个UIAbility。 如一般的…

Docker 启动alpine镜像中可执行程序文件遇到 not found

## 1. 问题&#xff1a; docker alpine镜像中遇到 sh: xxx: not found 例如&#xff1a; 在容器内/app/目录下放置了可执行文件abc&#xff0c;启动时提示not found /app/startup.sh: line 5: ./abc : not found ## 2. 原因 由于alpine镜像使用的是musl libc而不是gnu libc&am…

深度学习YOLO安检管制物品识别与检测 - python opencv 计算机竞赛

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络4 Yolov55 模型训练6 实现效果7 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习YOLO安检管制误判识别与检测 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&…

【论文阅读】SPARK:针对视觉跟踪的空间感知在线增量攻击

SPARK: Spatial-Aware Online Incremental Attack Against Visual Tracking introduction 在本文中&#xff0c;我们确定了视觉跟踪对抗性攻击的一个新任务&#xff1a;在线生成难以察觉的扰动&#xff0c;误导跟踪器沿着不正确的&#xff08;无目标攻击&#xff0c;UA&#x…

设计模式--模板方法外观模式

模板方法模式 场景&#xff1a;需使用代码方式实现&#xff0c;考完试后&#xff0c;将各个学生的试卷及答案誊抄一份。 假如有两个学生的试卷誊抄完毕. // 学生A public class TestPaperA {// 试题1public void testQuestion1() {System.out.println("问题一:XXXXXXXX…

【C++11】Lambda表达式使用详解

系列文章目录 C11新特性使用详解-持续更新 文章目录 系列文章目录简介一、特点二、语法结构三、实例1.排序2.容器赋值3.传参 简介 Lambda表达式是一种用于创建匿名函数的语法结构。它可以在需要函数对象的地方使用&#xff0c;而无需显式定义一个命名函数。Lambda表达式在C中…

【前端学java】Java中的接口和枚举概念(7)

theme: smartblue 往期回顾&#xff1a; 【前端学java】JAVA开发的依赖安装与环境配置 &#xff08;0&#xff09;【前端学 java】java的基础语法&#xff08;1&#xff09;【前端学java】JAVA中的packge与import&#xff08;2&#xff09;【前端学java】面向对象编程基础-类…

自定义函数

Spark自定义函数 spark 中的 UDF (UserDefinedFunction) 大家都不会陌生, UDF 其实就是将一个普通的函数, 包装为可以按 “行“ 操作的函数, 用来处理 DataFrame 中指定的 Columns. 例如, 对某一列的所有元素进行 1 操作, 它对应 mapreduce 操作中的 map 操作. 这种操作有的主…

《opencv实用探索·一》QT+opencv实现图片拼接和Mat转QImage

本文利用opencv实现了几个好用的功能&#xff0c;包含两个文件&#xff0c;如下&#xff1a; 源码放在文章末尾 imageProcessing类包含三个功能&#xff1a; 1、图像拼接 cv::Mat imageMosaic(cv::Mat mat1, cv::Mat mat2, MosaicMode mosaicMode);mat1和mat2为两个待拼接的…

Matplotlib实现Label及Title都在下方的最佳姿势

Matplotlib实现Label及Title都在下方的最佳姿势 1. 问题背景2. 基本思想&#xff08;可以不看&#xff09;3. 方法封装4. 调用实例5. 总结6. 起飞 1. 问题背景 用python绘制下面这种图的时候&#xff0c;一般用xlable作为子图的标题&#xff0c;这是因为plt.title()方法绘制的…

人工智能:科技魔法赋予生活新意

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

自学ansible笔记

一、认识ansible Ansible是一款开源自动化运维工具。它有如下特点&#xff1a; 1、不需要安装客户端&#xff0c;通过sshd去通信&#xff0c;比较轻量化&#xff1b; 2、基于模块工作&#xff0c;模块可以由任何语言开发&#xff0c;比较自由和开放&#xff1b; 3、不仅支持命…

WPF显示3D图形

C# 中的 WPF (Windows Presentation Foundation) 支持显示3D图形。WPF 使用 DirectX 作为底层图形引擎&#xff0c;这意味着它可以处理包括3D图形在内的复杂渲染任务。 在 WPF 中&#xff0c;你可以使用一些内置的类和控件来创建和显示3D对象。这包括 Viewport3D, Camera, Mod…