本人微信公众号: 前端修炼之路, 欢迎关注.
问题描述:
在 web-view 的 src 中, 引入了一个 html5 页面, 这个页面有个自动播放的音频.
在小程序中, 点击右上角关闭小程序后, Web-view 页面中的音频依然会播放.
期待现象
期待关闭小程序之后, 音频也停止.
通过查找文档, 发现没有直接提供方法, 网上找了一圈之后, 尝试的方案也都无法实现.
所以我这里想到的思路是, 当用户关闭小程序时, 应该销毁掉 Web-view. 可惜, 目前没有这个接口.
所以我就利用了模拟的方式来实现, 当前小程序页面 onHide 时, 就将 Web-view 的页面 src 属性清空.
后来经过测试发现, 在 iOS 平台下, 需要制定一个 url, 在 Android 平台下只需要清空. 另外为了防止造成缓存, 给 url 后面添加了一个随机的参数.
以下是代码片段.
- <script>
- export default {
- data() {
- return {
- webUrl: 'https://demo.com/weixin/index.html'
- }
- },
- onLoad() {
- },
- onHide(){
- // webview 关闭后, 刷新 url. 否则会造成音乐在后台继续播放的 bug
- if (wx.getSystemInfoSync().platform == "ios") {
- this.webUrl = 'https://demo.com/weixin/index.html?redirect=true';
- }else{
- // Android 系统下只能给空值
- this.webUrl = ';'
- }
- },
- onBackPress(){
- },
- methods: {
- }
- }
- </script>
注意:
以上代码是通过 uni-App 开发的. 如果在微信开发者工具中编辑, 需要符合微信小程序的语法.
2019 年 6 月 2 日 更新
经过测试, 发现以上代码并不是最好的选择. 因为当用户隐藏小程序后, 在最近使用的小程序中, 该小程序会继续在后台保留一段时间. 如果是替换 Web-view 的 url, 会造成音乐继续播放.
另外一个问题就是, 我以上代码判断了 iOS 和 andorid 两个平台. 其实现在想来并不需要.
综上所述, 以上代码参考意义并不大, 请使用监听 hashchange 方式来判断. 代码如下:
小程序中代码
- Page({
- data: {
- showed: false
- },
- // 小程序在前台
- onShow: function(){
- this.setData({
- showed: true
- });
- },
- // 小程序在后台
- onHide: function() {
- this.setData({
- showed: false
- });
- }
- })
Web-view 中代码
- Windows.addEventListener("hashchange", () => {
- var globalAudio = document.getElementById("player"); // 获取 audio HTMLDOM
- const hashData = parseURL(Windows.location.hash.slice(1));
- if (hashData.show) {
- const isShow = hashData.show === 'true';
- if (isShow) { // 切到前台
- if (globalAudio.paused) {
- globalAudio.play();
- }
- } else { // 切到后台
- if (globalAudio.play) {
- globalAudio.pause();
- }
- }
- }
- }, false);
- function parseURL(e) {
- var t, n, r, i = e, s = {};
- t = i.split("&"),
- r = null,
- n = null;
- for (var o in t) {
- var u = t[o].indexOf("=");
- u !== -1 && (r = t[o].substr(0, u),
- n = t[o].substr(u + 1),
- s[r] = n)
- }
- return s
- }
总结
通过 onShow 和 onHide 设置属性 showed 的值, 来判断用户的小程序是在前台还是后台.
因为是给 Web-view 的 src 动态修改 hash 值, 所以不会造成页面刷新, 相比直接修改 src 会更好.
然后在 Web-view 所在的页面中, 监听 hashchange 事件, 在事件中, 判断 hash 属性 show 的 true false 值, 空值音乐的暂停与播放.
2019 年 6 月 6 日 更新
本来以为监听 hash 值的变化, 已经是能完美的解决这个问题了. 但是经过测试之后, 发现了严重的问题: 安卓系统下, 用户点击物理返回按键, 会无法退出小程序
这个问题造成的原因是: 每次修改 hash 值时候, 都会添加一条历史浏览记录. 而用户点击返回按钮时, 就相当于点击浏览器的返回按钮. 自然就是会返回多次才能回到第一页, 然后才退出掉小程序.
这样的话, 用户体验就非常不好. 我首先想到的是, 调用 wx.miniProgram.navigateBack, 直接返回. 但是会报一个错误:
意思就是说, 我当前的 Web-view 是第一页, 不能再返回了.
最后还是通过阅读微信文档, 发现了 onPageStateChange 这个监听事件. 可以判断微信小程序是否在前台. 我最开始的时候, 测试过这个接口, 当时当时微信客户端没有升级, 所以我一直以为这个接口是不能用的呢.
其实这个接口是完全可以用的. 只不过需要微信版本在 7.0.3.
这样的话, 就可以将代码优化得非常少了.
- // wxml
- // 微信中的 JS
- Page({
- })
- // Web-view 页面中的 JS
- wx.ready(function() {
- var globalAudio = document.getElementById("player"); // 获取 audio HTMLDOM
- WeixinJSBridge.on('onPageStateChange', function(res) {
- // 注意: res.active 返回的是字符串类型的 true 和 false
- if(res.active == 'true'){
- globalAudio.play();
- }else{
- globalAudio.pause();
- }
- });
- });
主要就是, 不再采用监听 hash 值的变化了, 直接使用微信提供的接口. 非常好用.
来源: https://www.2cto.com/kf/201906/811781.html