移动端的坑们
阻止页面滑动
主要场景是在 IOS safari 浏览器,input 聚焦的时候,会顶起页面,并且会让长度溢出 viewport 的 div 变得可滚动,不符合预期
需要禁止滚动
// 阻止默认的滚动行为
function preventDefaultScroll(event: Event) {
event.preventDefault();
}
// 禁止页面滑动 for 移动端
function disableTouchScroll() {
document.addEventListener("touchmove", preventDefaultScroll, {
passive: false,
});
}
// 允许页面滑动
function enableTouchScroll() {
document.removeEventListener("touchmove", preventDefaultScroll);
}
// 禁止滚动
export function disableScroll() {
// 获取当前滚动位置
const scrollTop =
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop;
const scrollLeft =
window.pageXOffset ||
document.documentElement.scrollLeft ||
document.body.scrollLeft;
const stopScroll = () => {
window.scrollTo(scrollLeft, scrollTop);
};
// 保持滚动位置不变,并禁用滚动条
window.addEventListener("scroll", stopScroll);
disableTouchScroll();
return () => {
// 允许滚动
window.removeEventListener("scroll", stopScroll);
enableTouchScroll();
};
}
IOS 禁止 webview 的 bounce
JS 解决方案:可以尝试引入这个 js lib:https://github.com/lazd/iNoBounce (opens in a new tab)
其他场景:
html {
overscroll-behavior: none;
-webkit-overflow-scrolling: touch;
}
or 有些容器直接在 html 上 overflow: hidden
or 调用 JSB 让客户端控制
IOS webview text underline 没有颜色
text-decoration: underline solid 1px #000;
居然在 ios 上不展示了。。于是感觉是因为 color (opens in a new tab) 的兼容性不好
所以去掉 color,简单写,就有了
text-decoration: underline;
IOS 手机容器滚动条滑动不顺畅
overflow: auto;
-webkit-overflow-scrolling: touch;
移动端吸底输入栏方案
背景概述:在移动端的交互需要在键盘打开的时候,输入栏吸附在键盘的上方,很多编辑场景会用到(编辑器、评论输入)
这里仅做原理梳理,没有实际代码
安卓的表现和原理:
- 安卓软键盘弹起时页面直接压缩,内部是情况滚动
- 一定会触发 resize 事件
- 当输入框不在可视范围,会触发滚动,触发 scroll 事件
- 若页面本身可滚动,则使用页面滚动,键盘收起后不复原
- 否则整个页面上推,键盘收起后复原
- 键盘弹起后 fixed 布局不丢失,fixed 布局内的输入框不会触发滚动
iOS 的表现和原理:
未做任何处理时的表现:
- 页面上推不返回
- iOS 8+的设备,键盘是半透明的,会直接盖在页面上
- 不会触发 window resize
- 键盘弹起时,所有 fixed 布局失效,变为 absolute,滚动时随 html 滚动
- 因此即使是 fixed 布局,如果吸底的话,键盘弹起一定造成页面上移。
- 当 input 在页面下半屏(可能被键盘遮挡)时,会自动触发滚动,将输入滚动到可视范围
- 若当前页面已有滚动,则收起键盘后滚动位置不会还原
- 若当前页面无滚动,则页面会还原
IOS 13 推出 Visual_Viewport_API (opens in a new tab),在键盘出现后会触发这个事件 visualViewport
主要思路就是检查是否有 viewportChange(可以是 resize、visualViewport,innerHeight...,端上通信),在 Webview 上就可以得知有键盘弹出,控制对应输入栏所需固定的位置(高度)即可