场景
- 最近接到一个产品需求,需要在一个分享端外的
H5页面中增加一个弹窗,弹窗的内容是根据接口获取的一些消息,这些消息需要一条一条的轮播出来,并且每一条消息出来是都要有一个消息提示音。
前提
- 技术:
Vue2.0、vant2.12.27; - 环境:微信浏览器;
- 场景:定时自动弹窗、轮播消息并伴有声音、消息区域高度固定且超出滚动。
- 开发测试机型:
Android华为的 HarmonyOS 系统。
问题
- 消息超出设置滚动在
iOS上无法滚动; - 消息轮播时,声音播放不生效。
- 记住这里的前提,对后面很重要。
问题一
- 由于是一个弹窗并且需要背景色透明度,自然而然的想到了使用
vant中的overlay组件,于是就正常的使用这个组件作为弹窗的包裹层(为了偷懒,当然有现成的组件不用是傻子,不然为啥要引入组件库呢,对吧?)。 - 在开发过程中,由于没有真实的微信浏览器环境,所以使用的正常的浏览器环境,并且调试使用的是
Android华为的HarmonyOS系统。这两个原因都导致了这个问题。
基本结构
<overlay class="dialog-overlay">
<div class="content">
<div class="content-header" />
<div class="content-center" />
<div class="content-footer" />
</div>
</overlay>
content-center中就是显示消息的区域,对外层的dialog-overlay和content都设置了display: flex;并对content-center设置了下列属性:
flex: 1;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
-ms-overflow-style: none;
overflow: -moz-scrollbars-none;
...
- 在本地开发完成后发现是可以用的,于是就发布部署到
dev环境,通过分享到自己的微信测试(iOS),使用测试的Android测试,发现都无法滚动。
查找原因
- 是否是上层有什么元素遮挡,导致手指按下未触到可滚动的元素区域,使用
vconsole打开debug模式,审查元素,元素正常无遮挡。 - 是否是属性未生效,检查属性问题;亦或者是
flex属性导致无法滚动;都尝试过发现还是无法滚动,且对比其他同样在微信浏览器环境下设置了同样的属性是可以生效(滚动)的。 - 在对比其他微信浏览器环境下可滚动的元素发现,唯一有一点不同的就是最外层的元素不一样,于是去掉
overlay组件,改用div,重新发布部署后iOS和Android都可用。
- 查找相关问题,发现很多人都遇到过,所以只要定位到问题,你遇到的基本上前面都有人遇到了,如何解决就变得简单了。关键是学会如何定位排查问题。
问题二
- 在做之前,我写了一个
demo在手机浏览器环境试过,发现完全没有问题,觉得就这?这么简单的吗? - 万万没想到的是,就这,我调试部署了好几次最后才将其解决。
就这方案一
- 方案一也就是
demo中使用的方式,代码异常的简洁,如下:
const mp3 = new Audio('xxx.mp3');
setInterval(() => {
mp3.load();
mp3.play();
}, 1000)
- 是不是非常的简单,在我华为
HarmonyOS系统的测试机上可是一点问题都没有,非常的流畅,于是自行的提到 dev 环境,并分享微信中打开体验。iOS打开没有声音???一定是我没有开手机音量,开启所有音量打开还是没有声音。我:......。于是拿另外的Android测试机试试,发现依旧没有声音。
打击方案二
- 由于方案一的失败,依然觉得这个应该也不是很能,一定是我打开的方式不对,既然直接 new 不行,那我把它放到 HTML 中总行了吧。于是乎改成了下面的代码:
// html
<audio ref="audioRef">
<source src="xxx.mp3" type="audio/mp3" />
</audio>
js
const audioRef = this.$refs.audioRef;
setInterval(() => {
audioRef.load();
audioRef.play();
}, 1000)
- 是不是依然很简单,于是又一次发不到
dev测试,测试结果发现iOS依旧不行,Android偶尔有声音,但是消息出现和声音对不上,有时候也没有声音。
查阅方案三
- 前两个方案都不行,那只能搜索看一下有没有啥解决方案了。查阅发现自 2020年4月8日起,
Android微信浏览器环境的音频自动播放做了调整,Android微信内网页音频自动播放能力调整。 - 于是乎,只要我
Android上可以,那iOS基本上应该是没问题了,通过之前的积累知道微信浏览器有这样一个事件:
document.addEventListener(
'WeixinJSBridgeReady',
() => {
console.log('WeixinJSBridgeReady');
},
false
);
- 于是我尝试基本页面
mounted中,监听WeixinJSBridgeReady,在微信环境准备就绪后去初始化我们想播放的音频,如下:
document.addEventListener(
'WeixinJSBridgeReady',
() => {
console.log('WeixinJSBridgeReady');
const audio = document.createElement('audio');
audio.setAttribute('id', 'msgAudio');
audio.setAttribute('src', 'https://cd-user-upload.hongsong.club/txd/living-h5/hint-sound.mp3');
document.body.appendChild(audio);
},
false
);
- 在子组件弹窗中使用
const mp3 = document.getElementById('msgAudio');
this.timer = setInterval(() => {
if (i < len) {
if (mp3) {
mp3.load?.();
mp3.play?.();
}
this.renderList.push(this.totalList[i]);
i++;
this.pushToView();
} else {
this.cantScroll = false;
clearInterval(this.timer);
}
}, 1000);
- 这里顺便安利一个方法
scrollIntoView,可以将制定元素滚动到可视区域。
pushToView() {
this.$nextTick(() => {
const itemList = document.querySelectorAll('.message-item');
itemList[itemList.length - 1]?.scrollIntoView(false);
});
},
- 发布部署到
dev直接用Android测试,发现声音随消息一起播放弹出,避免偶然,多次关闭,打开都没有问题;切换iOS果然也是正常的。
总结
- 在开发过程中出现问题是很正常的,尤其是有些环境不好测试,开发时没有对应的环境调试。出现问题后可以通过自己的一些猜测去尝试解决;如果无法解决可以查阅网上的资料,描述自己的问题。
- 如果是工作没多久的没有啥经验的话,先尝试自己解决(一定要先自己尝试),多次尝试实在无法解决可以找带自己的前辈或
leader请教。
往期精彩
- Node.js 版本管理工具 n 最全使用手册
- video 标签在项目中实战、属性及事件详解
- 磕磕绊绊的 4 年前端er,一次含泪总结
- 前端还不会 Nginx 吗?快来学起来
- 金九前端面试总结!
- 从0搭建Vite + Vue3 + Element-Plus + Vue-Router + ESLint + husky + lint-staged
- 「前端进阶」JavaScript手写方法/使用技巧自查
- 公众号打开小程序最佳解决方案(Vue)
- Axios你可能不知道使用方式
「点赞、收藏和评论」
❤️关注+点赞收藏+评论+分享❤️,手留余香,谢谢🙏大家。