Safari 浏览器踩坑记录
音频加载
近期做了个小游戏,需要用到 mp3
文件,为了不让用户等待做了预加载,实现方式就是
1 | const audio = new Audio() |
这样再监听 canplay
事件,即可拿到是否加载完成,加载多个并做了进度条
但后来朋友反馈发现,iPhone
手机进度一直是 0%,原因有两个
iOS 加载音频非 WIFI 下不能预加载,需要用户同意
也就是
audio.load()
需要在一个用户操作事件中,比如onClick
本想着这就解决了,在同一个点击事件里先加载,做了个异步,等待加载完成后继续执行播放,结果又不对了
播放前不能有
await
也就是调用
audio.play()
之前不能有await
,需要先执行加载,再进行播放于是最后做了设备类型判断,如果是
iOS
设备,就需要先点击加载音频,加载完后才会出现开始按钮
滚动回弹
近期工作中遇到了这个问题,Safari
浏览器如果滚动到最下面先停一下,然后还能继续往上拉,松开就有个很回弹的回弹
关掉这个效果很简单,在滚动元素上加个样式即可
1 | -webkit-overflow-scrolling: auto; |
100vh 的问题
这也是工作中遇到的,最先是 Safari
遇到的,但按理说是所有移动端浏览器都可能有的
正常写个 100vh
就是窗口高度,配合 calc
可以很方便的设置想要的高度,但移动端会有个问题
就是地址栏或者 tab bar
也会计算在 100vh
里,所以实际获取到的高度就是 可视区域 + tab bar
所以需要用 svh
,这个单位可以减掉 tab bar
但实际有个问题就是,有些浏览器还没支持 svh
,这就需要自己计算了,好在已经有人实现了类似的功能,使用这个库
1 | import 'large-small-dynamic-viewport-units-polyfill' |
其实它实现的功能很简单,就是获取可视区域高度,并声明一个叫 --1svh
的 CSS 变量
1 | var svh = document.documentElement.clientHeight * 0.01; |
使用时就使用 calc
自行计算 calc(var(--1svh, 1vh) * 100);
,这样就相当于是 100svh
此时只需要写一个 @supports
根据浏览器支持自动选择用哪个即可
1 | @supports (height: 100svh) { |
最后
上面说的小游戏在这里:https://games.imba97.cn