ios H5踩坑之旅汇总

2,581 阅读6分钟

1. position: absolute;

问题: position: absolute 的元素不能完全脱离父节点,不能完全的意思是能够在父节点内绝对定位,但不能超出父节点绝对定位,即便父节点不是relative。
解决: 如果需要做全屏的图片,则需在根节点body下创建一个新元素。例如:

<body>
  <div style="position: fixed;top: 0;bottom: 0;left: 0;right: 0;">
    <img src="xxx.jpg" style="width: 100%;height: 100%;">
  </div>
</body>

参考:
进展: ios11以后无此bug

2. user-select: none

问题: 设置全局user-select: none 会导致输入框无法输入的问题
解决: *:not(input, textarea) { user-select: none; }

3. DOM.style = 'xxx';

问题: DOM.style = 'width: 10px;height: 10px';不生效
解决1: DOM.style.width = '10px'; DOM.style.height = '10px';
解决2: DOM.style.cssText = 'width: 10px;height: 10px';

4. 微信开发新坑iOS上虚拟键盘引起的触控错位

问题: 微信开发新坑iOS上虚拟键盘引起的触控错位。视野看到的元素跟元素实际位置不一致,导致元素不能外部触发事件
解决: 在输入框失焦时调用

let top = target.getBoundingClientRect().top;
window.scrollTo(0, 0);
window.scrollTo(0, top);

参考: 微信开发新坑iOS上虚拟键盘引起的触控错位

5. 滑动顺滑

问题1: 解决顺滑问题
解决1: 在需要overflow的元素上增加-webkit-overflow-scrolling: touch;,但是这样会引起一些恶心的问题,看以下问题x
问题2: 无法向下滑动,一滑把整个窗口都向上移
解决2: 引入inobounce.js,但是仍然存在个别情况会失败,再看解决2.1
解决2.1: 在需要overflow的元素上加上height: 101%,大于100即可
问题3: 某些机型的文字初始位置在可视窗口范围外的文字,在滚动到可视范围时不能显示,需点击一下文字所在的元素才出现,但在可视范围外的文字又进入不能显示的状态
解决3: 在文字所在的元素或其父级元素上增加transform: translateZ(0)或者transform: translate3d(0, 0, 0),使用硬件加速即可
参考: iOS Safari浏览器上overflow: scroll元素无法滑动bug解决方法整理

6. iframe宽度大于父容器

问题: 如果iframe内的元素宽度是绝对值xxxpx,大于父容器宽度,则iframe会被撑大
解决: 在iframe外加一个容器,并设置相应style,iframe本身也要设置相应style和attribute。但最难理解的是*width这个hack

<wrapper style="overflow:auto;-webkit-overflow-scrolling:touch;">
  <iframe scrolling="no" width="100%" height="100%" style="width: 1px;min-width=100%;*width=100%;height:100%;"></iframe>
</wrapper>

参考: IOS webview iframe 宽度超出屏幕解决方案

7. 轻触输入框不能唤起软键盘

问题: 轻触输入框不能唤起软键盘
解决: 在点击输入框时触发输入框的focus操作@click="e => e.target.focus()"
参考: 移动端input输入框,首次点击能拉起键盘,再次点击拉不起键盘

8. 微信二维码不能识别

问题: 微信二维码不能识别 解决: 设置了<body style="all: initial;">,暂未得知原理

9. 刘海屏和全面屏的底部输入框点击聚焦不稳定

问题: 刘海屏和全面屏的底部输入框点击聚焦不稳定
解决: 底部输入框增加csspadding-bottom: constant(safe-area-inset-bottom);padding-bottom: env(safe-area-inset-bottom);
参考: safe-area-inset-bottom iphone

10. 视频重放没有画面

问题: 当一个视频播放完毕,点击重播时,画面全黑没有动画
解决: 将视频设置成内联模式 'playsinline'=true 'webkit-playsinline'=true 'x5-playsinline'=true //微信
参考:

11. 视频播放有进度条和声音但是没有画面

问题: 当进行这样一个操作步骤,播放视频->点击全屏->播放结束->退出全屏->重播视频,的操作后,并且在代码中加上@ended="e.target.style.display = 'none'",视频就会出现有进度条和声音没有画面这样的情况
解决: 猜想是ios的全屏不支持video的display为none的情况,于是改成@ended="e.target.style.visible = 'hidden'",问题解决了~
参考:

12. 图片不能实时展示出来

问题: 比如有个图片P,有ABC三个区域,在首次加载图片时,A区域在屏幕可视范围内,B区域不在范围内。A区域是立即可视的,理论上来说,B区域也应该会显示,但当手指滑动到B区域到可视范围内,B区域却渲染不出来,呈空白一片,只能用手指点击一下B区域,画面才渲染出来。然后滑动到C区域,B区域这时不在可视范围内,C点击出现后,滑动回到B区域,可此时B又不见了,最后点击一下又出现了。因此规律是不再可视范围内的区域不会被渲染,直至有点击交互为止。
解决: 猜想是显卡问题,就使用3d硬件加速,加上transform: translateY(0)或者transform: translate3d(0, 0, 0)就解决了
参考: 一篇文章说清浏览器解析和CSS(GPU)动画优化

13. 元素旋转后滚动条不能正常使用

问题: 加上transform: rotate(90deg)的元素如果内容溢出并且有滚动条,原本的纵向滚动并没有变成横向滚动,也就是说:横向滚动会使内容上下移动。
解决: 重写元素的 touch 方法,改变元素的 scrollTop
参考:

14. iPhoneX的底部栏适配

问题: 由于iPhoneX底部没有了实体 home 键,也就没有了 home bar,而是用屏幕内的上拉按钮来实现,但这个按钮遮挡住屏幕的实际位置,因此需要更佳的解决方案。
解决1: 占用该位置,meta标签加上viewport: cover属性<meta name="viewport" content="viewport-fit=cover">,另外 html , body 的 height 设置为 100vh,不能为100%,html, body { height: 100vh; }
特殊说明1: 这个方案有时不需要执行,在微信、safari、uc是全部铺满,但有些浏览器是不会自动铺满的。
解决2: 不占用该位置,使用 css constant() 函数和 safe-area-inset-xxx(top/bottom/left/right) 的结合

body {
  padding-top: constant(safe-area-inset-top);       /* 为导航栏+状态栏的高度 88px */
  padding-left: constant(safe-area-inset-left);     /* 如果未竖屏时为0 */
  padding-right: constant(safe-area-inset-right);   /* 如果未竖屏时为0 */
  padding-bottom: constant(safe-area-inset-bottom); /* 为底下圆弧的高度 34px */
}

特殊说明2: 有些浏览器(如企业微信)会自动加上安全区处理,即不占用顶部导航栏和底部上拉栏,因此加上该属性后会叠加 padding 的值,实际内容区的大小会被进一步压缩
参考: safe-area-inset-bottom iphone

15. iPhoneX上下滑动不能回弹

问题: iPhoneX 上下滑动不能回弹,仅仅在 safari 等有地址栏和书签栏
解决: html 容器不能用min-height: 100vh;,只能用min-height: 100%;

16. 点击具有tabindex的元素,会触发blur事件

问题: 设置一个元素加属性 tabindex="1",并且 focus() 这个元素,在点击这个元素或这个元素内部的时候会触发元素的 blur 事件
解决: 设置元素的 touchstart 阻止事件传递 dom.addEventListener('touchstart', e => e.stopPropogation())
参考:

17. Safari的100vh导致页面有滚动条

问题: 如题。
解决:height: 100vh改成height: calc(var(--vh, 1vh) * 100),其中的--vh的设置方法为document.body.style.setProperty('--vh', window.innerHeight / 100 + 'px')
参考: 如何解决safari浏览器100vh有滚动条问题