中高级前端必须注意的40条移动端H5坑位指南( 五 )


了解什么是BFCache再对症下药,解决方案就在window.onunload上做文章 。
// 在新页面监听页面销毁事件window.addEventListener("onunload", () => {// 执行旧页面代码});复制代码若在Vue SPA上使用keep-alive也不能让页面刷新,可将接口请求放到beforeRouteEnter()里 。
当然还有另一种解决方案 。pageshow事件在每次页面加载时都会触发,无论是首次加载还是再次加载都会触发,这就是它与load事件的区别 。pageshow事件暴露的persisted可判断页面是否从BFCache里取出 。
window.addEventListener("pageshow", e => e.persisted && location.reload());复制代码若浏览器不使用<meta http-equiv="Cache-Control" content="no-cache">禁用缓存,该解决方案还是很值得一用 。
解析有效日期在苹果系统上解析YYYY-MM-DD HH:mm:ss这种日期格式会报错Invalid Date,但在安卓系统上解析这种日期格式完全无问题 。
new Date("2019-03-31 21:30:00"); // Invalid Date复制代码查看Safari相关开发手册发现可用YYYY/MM/DD HH:mm:ss这种日期格式,简单概括就是年月日必须使用/衔接而不能使用-衔接 。当然安卓系统也支持该格式,然而接口返回字段的日期格式通常是YYYY-MM-DD HH:mm:ss,那么需替换其中的-为/ 。
const date = "2019-03-31 21:30:00";new Date(date.replace(/-/g, "/"));复制代码修复高度坍塌当页面同时出现以下三个条件时,键盘占位会把页面高度压缩一部分 。当输入完成键盘占位消失后,页面高度有可能回不到原来高度,产生坍塌导致Webview底色露脸,简单概括就是输入框失焦后页面未回弹 。

  • 页面高度过小
  • 输入框在页面底部或视窗中下方
  • 输入框聚焦输入文本
只要保持前后滚动条偏移量一致就不会出现上述问题 。在输入框聚焦时获取页面当前滚动条偏移量,在输入框失焦时赋值页面之前获取的滚动条偏移量,这样就能间接还原页面滚动条偏移量解决页面高度坍塌 。
const input = document.getElementById("input");let scrollTop = 0;input.addEventListener("focus", () => {scrollTop = document.scrollingElement.scrollTop;});input.addEventListener("blur", () => {document.scrollingElement.scrollTo(0, scrollTop);});复制代码修复输入监听在苹果系统上的输入框输入文本,keyup/keydown/keypress事件可能会无效 。当输入框监听keyup事件时,逐个输入英文和数字会有效,但逐个输入中文不会有效,需按回车键才会有效 。
此时可用input事件代替输入框的keyup/keydown/keypress事件 。
简化回到顶部曾几何时编写一个返回顶部函数麻烦得要死,需scrollTop、定时器和条件判断三者配合才能完成 。其实DOM对象里隐藏了一个很好用的函数可完成上述功能,一行核心代码就能搞定 。
该函数就是scrollIntoView,它会滚动目标元素的父容器使之对用户可见,简单概括就是相对视窗让容器滚动到目标元素位置 。它有三个可选参数能让scrollIntoView滚动起来更优雅 。
  • behavior:动画过渡效果,默认auto无,可选smooth平滑
  • inline:水平方向对齐方式,默认nearest就近对齐,可选start顶部对齐、center中间对齐和end底部对齐
  • block:垂直方向对齐方式,默认start顶部对齐,可选center中间对齐、end底部对齐和nearest就近对齐
const gotopBtn = document.getElementById("gotop-btn");openBtn.addEventListener("click", () => document.body.scrollIntoView({ behavior: "smooth" }));复制代码当然还可滚动到目标元素位置,只需将document.body修改成目标元素的DOM对象 。一行核心代码就能搞掂的事情为何还编写那么多代码去完成,不累吗?
简化懒性加载与上述简化回到顶部一样,编写一个懒性加载函数也同样需scrollTop、定时器和条件判断三者配合才能完成 。其实DOM对象里隐藏了一个很好用的函数可完成上述功能,该函数无需监听容器的scroll事件,通过浏览器自身机制完成滚动监听 。
该函数就是IntersectionObserver,它提供一种异步观察目标元素及其祖先元素或顶级文档视窗交叉状态的方法 。详情可参照MDN文档,在此不作过多介绍 。
懒性加载的第一种使用场景:图片懒加载 。只需确认图片进入可视区域就赋值加载图片,赋值完成还需对图片停止监听 。
<img data-src=https://www.isolves.com/it/cxkf/ydd/html5/2021-03-18/"pig.jpg">复制代码const imgs = document.querySelectorAll("img.lazyload");const observer = new IntersectionObserver(nodes => {nodes.forEach(v => {if (v.isIntersecting) { // 判断是否进入可视区域v.target.src = https://www.isolves.com/it/cxkf/ydd/html5/2021-03-18/v.target.dataset.src; // 赋值加载图片observer.unobserve(v.target); // 停止监听已加载的图片}});});imgs.forEach(v => observer.observe(v));复制代码


推荐阅读