H5 踩坑日记

H5 踩坑日记
移动端 H5 页面和 PC 端页面开发虽然用到的技术栈一样,但移动端 H5 页面需要注意的问题比 PC 端要多得多,尤其是兼容性的问题,IOS 和 安卓之间的差异性,安卓机不同版本的机型,为了兼容绝大部分用户,往往需要适配不同版本的机型,下面就我在开发项目过程中出现的问题进行总结(基于 Vue 框架下的代码)。
1. IOS 键盘唤起后收起页面不归位
问题描述:
在 IOS 设备上,键盘弹出,页面整体内容上移,但键盘收起后页面内容不下滑。
问题分析 :
固定定位的元素,在元素内 input
框聚焦的时候,弹出的软键盘占位,失去焦点的时候软键盘消失,但软键盘还是占位的,导致 input
框不能再次输入。
解决办法 :
在失去焦点时重置滚动元素的滚动位置。
<script lang="ts" setup>
import { get } from 'lodash-es';
function handleBlur() {
const isIOS = /(iPhone|iPad|MacWechat)/i.test(get(window.navigator, 'userAgent', 'node'));
if (isIOS) {
setTimeout(() => {
const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;
const scrollY = scrollHeight > 1 ? scrollHeight - 1 : scrollHeight + 1;
window.scrollTo(0, scrollY); // 让页面滚动一像素
}, 200);
}
}
</script>
<template>
<input @focus="handleFocus" @blur.prevent="handleBlur" />
</template>
拓展知识 :
position: fixed
在 IOS 中,收起键盘会被顶上去,特别是在第三方键盘中。
2. iOS 上 sticky 元素遮挡滚动条
问题描述:缺少原因分析
在 iOS 设备上,使用 position: sticky
的元素会遮挡滚动条,导致页面效果不美观。
问题分析 :
这主要与 IOS 的兼容性有关:position: sticky
元素的行为与其最近的可滚动祖先元素有关。在 iOS 上,如果 sticky
元素的滚动容器(祖先元素)具有 overflow: scroll
或 overflow: auto
,可能会出现意外的定位行为。例如,iOS 上可能会发生 sticky
元素在滚动时表现异常,或者被滚动条遮挡。
解决办法:
将 overflow-y: scroll
应用于 .container
元素即可解决这个问题。
<template>
<div class="page">
<!-- other code.... -->
<div class="container">
<div class="sticky-box">sticky-box</div>
<div class="content height">height: 1200PX</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.page {
width: 100%;
height: 100vh;
padding-bottom: 56px;
overflow-y: scroll;
text-align: center;
background-color: #fff;
}
.container {
padding-top: 100px;
.sticky-box {
position: sticky;
z-index: 99;
top: 0;
line-height: 50px;
background-color: #fafafa;
box-shadow: 0px 4px 18px 2px rgba(4, 0, 0, 0.1);
}
.content {
height: 1200px;
padding: 40px;
background-color: #fafafa;
}
}
</style>
3. IOS滚动不流畅
解决办法:
在滚动的元素上添加CSS
overflow-y: auto;
-webkit-overflow-scrolling : touch;
在iOS 13之后,不需要再设置-webkit-overflow-scrolling:touch
了,因为所有可滚动的框架,或者设置 overflow 滚动的元素默认都是弹性效果了
4. flex-1 的后代元素无法获取高度
问题分析:
在使用 CSS 的 flexbox 布局时,flex: 1 表示一个弹性项目将占据父容器的可用空间,以实现自动调整大小的效果。然而,有时候在某些情况下,设置 flex: 1 并不足以使子元素的高度生效。这是因为在默认情况下,弹性项目的高度是由其内容的高度决定的,而不是由父容器撑开。
解决办法:
添加 height: 0 是为了确保父容器的高度为 0,然后使用 flex: 1 将父容器的高度撑开,最后通过设置子元素的 align-self: stretch 和 height: 100% 来使子元素的高度与父容器一致。
.page{
display: flex;
.parent {
flex: 1,
height: 0;
.children {
height: 100%; /* height 设置生效 */
}
}
}
5. 解决 iOS 微信 H5 页面分享失败的问题:hash 模式下分享失败:
问题描述:
Vue 中路由使用 hash 模式,开发微信 H5 页面分享时在安卓上设置分享成功,但是 IOS 的分享异常, IOS 当前页面分享给好友,首次进入页面展示正常,如果二次分享,则跳转到首页;使用 Vue Router 跳转到第二个页面后在分享时,分享设置失败;但以上在安卓上分享都显示正常。
问题分析:
- iOS 微信内置浏览器对 hash 的处理:
iOS 微信内置浏览器可能在分享时忽略 URL 中的 hash 部分,导致分享的链接在其他设备上打开时,hash 信息丢失。这就可能导致二次分享或者重新打开链接时,无法正确解析路由,导致跳转到首页。 - 二次分享跳转到首页:
当页面通过 hash 模式设置路由后,iOS 微信在生成分享链接时,可能将 hash 部分剥离掉,导致分享的 URL 没有包含正确的路由信息。在用户二次分享时,由于 URL 不完整,默认会跳转到首页。 - 在 Vue Router 跳转到第二个页面后分享失败:
当你从一个页面跳转到另一个页面时,如果没有正确更新微信 JS-SDK 的配置(比如调用wx.config
),可能会导致分享设置失败。这是因为微信需要每次在页面加载或路由变化时重新配置 JS-SDK 以确保分享的内容是正确的。
解决办法:
-
在路由跳转后重新初始化微信 JS-SDK:
确保每次路由切换后都重新调用wx.config
,并设置分享内容。你可以在每次路由切换完成后(例如使用router.afterEach
)重新进行微信分享配置。router.afterEach((to, from) => { // 在这里调用 wx.config 并设置分享参数 });
-
处理 iOS 分享链接 :
在生成分享链接时,可以手动拼接参数,避免微信自动处理 URL 导致 hash 丢失。你可以在分享时使用完整的 URL(包括 query 参数)来代替 hash。let url = location.href.split('#')[0]; // 获取当前页面 URL,去掉 hash let fullUrl = `${url}?path=${encodeURIComponent(to.fullPath)}`; // 拼接分享的完整链接
- 监控微信浏览器环境并做兼容处理 :
在代码中检测是否为微信浏览器,并根据不同的平台做兼容处理,例如对 iOS 的分享逻辑进行单独处理。 - 使用 history 模式来替代 hash 模式:
君子不立于危墙之下,如果可以,建议将 Vue Router 的模式切换为history
模式,这样分享时 URL 中不会有#
,能够更好地兼容 iOS 和 Android。
6. 解决 iOS 微信 H5 页面分享失败的问题:分享配置在多页面间的正确处理方法
问题描述:
假设有:PageA、PageB、PageC,其中 PageA 和 PageC 需要打开分享、PageB 需要关闭分享,根据 jssdk 隐藏功能按钮接口文档 我们在 PageB中设置 hideMenuItems
。
此时,当你从 PageB 页面前往任意页面都将发现分享失效
问题分析:
理论上你触发关闭了之后如果不重新设置 showMenuItems,其它页面也是没有分享内容的。
解决办法:
- 在每个页面的路由配置中,分别设置 wx.config 和 wx.ready,确保每次进入页面时重新初始化微信分享配置。
- 我们可以在每次进入页面时都执行
showMenuItems
:
- 离开 PageB 页面的时候重新开放
showMenuItems
配置(注:需要在页面初始化的时候就注册好 api ):beforeRouteLeave(to, from, next) { wx.showMenuItems({ menuList: ['menuItem:share:appMessage', 'menuItem:share:timeline', 'menuItem:share:qq', 'menuItem:share:weiboApp', 'menuItem:share:facebook', 'menuItem:share:QZone'] }); next(); }
总结:
微信 H5 开发涉及诸多知识点,比如登录授权、JS-SDK 授权等等。然而,在这里我们仅仅讨论了分享功能的配置。事实上,H5 项目中的“坑”远不止这些,每一个细节都可能隐藏着复杂的挑战。开发的旅程就是在不断探索中前行,正所谓生命不息,踩坑不止……