评论

[填坑手册]小程序web-view组件实战与踩坑

小小web-view,大大真滋味

首先,根据官网文档可以知道 只有非个人 的小程序才可以使用web-view组件,如果你的个人开发者,可以跳过这篇文章。

一、使用web-view以及它的好处

1、己方账号(第三方)与小程序openId/UnionId的关联绑定,实现免登陆

比如你是某门户网站S,你要识别自己小程序上的用户与网站用户的关系,你可以通过三种方法绑定关系,公众号,小程序源生,小程序web-view内嵌跳转三种方法

2、内嵌H5的富文本,减少重复开发

比如你是门户网站,社区,以往有大量的新闻和帖子,里面带了各种css样式的富文本,小程序源生是无法直接读取的,需要大量转化,这时候直接内嵌这些H5新闻,大大降低开发成本

3、热更新,减少发布审核

某些需要经常更新的内容、公告、活动页,内嵌H5可以减少频繁提交小程序审核

二、小程序功能赋权

为H5提供各种小程序才有的功能,比如录音,扫一扫等。

注意事项

  1. 多场景判断,建议使用官方API: wx.miniProgram.getEnv
  2. H5唤醒一些小程序API有一定的延时,0.3~1秒
  3. 请调用小程序专用的JSSDK,同一个jssdk,但是webview的功能收到限制,和之前微信打开H5有所不同
  4. 小程序自动获取加载H5的title
  5. H5中iframe的url必须也是业务域名
  6. web-view一定是撑满全屏的,自定义顶部菜单,悬浮的都没用

三、小程序和H5之前的互相通讯

1、 从小程序 ==>> h5

小程序控制H5,可以直接用src路径传参的形式,比如

<!--  小程序端 HTML -->
<web-view  src="//URL?a=param1&b=param2"></web-view>

避免在链接中带有中文字符,在 iOS 中会有打开白屏的问题,建议加一下 encodeURIComponent。

2、 从 H5 ==>> 小程序

这里我们知道bindmessage是小程序用来监听H5的推送的内容,但是这里不大不小的坑!就是它的三个出发场景:

  • 小程序后退:使用接口名 wx.miniProgram.navigateTo,wx.miniProgram.navigateBack,wx.miniProgram.switchTab 等切换小程序页面/场景的API时候都会出发
  • 分享:这个就是当你点分享小程序的时候,会接受到H5之前发送的postMessage
  • 组件销毁,web-view组件销毁,类似 wx.miniProgram.redirectTo 都会触发。
<!--  小程序端 HTML -->
<web-view bindmessage="handleGetMessage"  src="{{openUrl}}"></web-view>
// 小程序端 JS -->
Page({
  /**
   * 页面的初始数据
   */
  data: {
    openUrl: "",
  },
  /**
   * 获取请求数据
   */
  handleGetMessage: function (e) {
    console.log(e.detail.data);
    }
  },
})
<!-- h5端 HTML和JS -->
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script>
<script>
wx.miniProgram.postMessage({
    data: {
        link: "//test.com",
        title: "一起学习,一起进步"
    }
});
//wx.miniProgram.redirectTo({
//  url:"/pages/inner/index?source=123"
//})
wx.miniProgram.navigateBack({delta: 1})
</script>

注意事项

  1. 那些H5控制小程序的跳转路径必须是“/”开头,如 “/pages/xxx/xxx”,且路径必须在app.json里有,地址错误的话,有时不报错。
  2. postMessage的json必须是data开始,不然接收不到数据。

四、bindmessage接收到消息有3个重要特性(重点)

  1. 接收可以是H5之前几分钟前发送postMessage,不一定是即刻发出的。

  2. 之前发出的 postMessage的DATA信息会累加,当触发bindmessage接收的时候是一个数组。

  3. 当bindmessage 再次 接收到数据,之前发送的数据不会被清空,将累加一起返回,获取时要判断好数组的角标

五、Tips

1、在IDE工具中如何调试H5


可以在 web-view 组件上通过右键 - 调试,打开 web-view 组件的调试。

2、内嵌H5缓存问题

web-view加载的H5具有很重的缓存,如果需要调试,可以通过在url后面加时间戳的方式解决。

3、小程序关闭,H5背景音乐仍然在播放问题

小程序已经关闭,但是H5自带的背景音乐仍然在手机后台播放的问题。这里可以利用一个属性:

visibilitychange:页面可见性状态

简单的说,浏览器标签页被隐藏或显示的时候会触发visibilitychange事件。

var statusBeforeHide = true; //初始化页面的状态
var music = document.getElementById("xxx");
// 更改音乐播放状态
function setChangeMusic() {
    if (document[hiddenProperty]) {
        // 页面隐藏
        if (statusBeforeHide) {
            music.pause(); // 暂停
        }
    } else {
        // 页面显示
        if (statusBeforeHide) {
            music.play() //如果statusBeforeHide是true, 继续播放
        }
    }
}

let hiddenProperty = ('hidden' in document) ? 'hidden'
        : ('webkitHidden' in document) ? 'webkitHidden'
            : ('mozHidden' in document) ? 'mozHidden' : null;
if (hiddenProperty) {
    let visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange');
    let onVisibilityChange = () => {
        //console.log('visibilityChange');
        setChangeMusic();
    };
    document.addEventListener(visibilityChangeEvent, onVisibilityChange);
} else {
    console.log("不支持这个api");
}

总结,web-view还是非常实用的组件,且用且珍惜~

往期回顾:

最后一次编辑于  2021-09-13  
点赞 32
收藏
评论

35 个评论

  • (「・ω・)「嘿
    (「・ω・)「嘿
    2022-11-30

    bindmessage 接收到数据,之前发送的数据会累加;这个数据量上限是多少呢

    2022-11-30
    赞同
    回复
  • :)
    :)
    2022-10-24

    小程序嵌入的web-view,怎么打开聊天素材内的图片呢,谢谢?

    2022-10-24
    赞同
    回复
  • 吴海鹏
    吴海鹏
    2022-09-22

    楼主你好,由于postMessage的DATA信息会累加,我的webview承载的A页面使用了postMessage数据,然后跳转到B页面,B页面没有触发更新postMessage的数据,但是在点击分享的时候还是获取了A页面的数据,这时候我没办法区分是哪个页面传进来的。

    ps:A,B页面都不是我们团队的,可能还有CDEF等等页面,没办法约定DATA把当前路由传递进来。这种情况能解决吗?

    有没有办法监听webview内H5路由的变更呢?

    2022-09-22
    赞同
    回复
  • Nobody.
    Nobody.
    2022-07-28

    web-view可以通过字段控制显示隐藏吗,比如wx:if wx:hidden

    2022-07-28
    赞同
    回复 1
    • 游戏人生
      游戏人生
      2022-08-01
      if可以  hidden不行,但意义是什么呢?。。。现在的 web-view都是撑满全屏的
      2022-08-01
      回复
  • Hann
    Hann
    2022-05-12

    微信小程序为什么不能像app一样用evalJS()操作h5里面的方法,希望能尽快开放

    2022-05-12
    赞同
    回复
  • 谢志杰
    谢志杰
    2022-05-05

    web-view 部分安卓机打开是空白页面,晕 不知道怎么解决

    2022-05-05
    赞同
    回复 1
    • 游戏人生
      游戏人生
      2022-05-05
      看下url是不是有登录或者其他什么重定向,#号什么的
      2022-05-05
      1
      回复
  • 🐳泡芙🐳
    🐳泡芙🐳
    2022-04-01

    请教个问题,小程序嵌套webview  H5 里面可以上传图片吗 chooseImage uploadImage

    2022-04-01
    赞同
    回复 1
    • 游戏人生
      游戏人生
      2022-04-01
      支持的
      2022-04-01
      回复
  • 因你而悦
    因你而悦
    2022-03-08

    作者您好,最近我有一个需求就是h5页面需要小程序传递的参数,在web-view组件上我将参数拼接到url后面。但是在h5中怎么都接收不到我拼接的参数,在h5中打印window.location.search中看不到我传递的参数,请问我是哪里不对呢?

    2022-03-08
    赞同
    回复 3
    • 游戏人生
      游戏人生
      2022-03-08
      是不是有重定向跳转?
      2022-03-08
      回复
    • 。。。。
      。。。。
      2022-04-18回复游戏人生
      我也遇到了这个问题;我的h5用vue做的,我在index.html页面和app.vue都获取不到window.location.search的值;是因为在本地的原因吗?是不是上线了才能获取到值啊
      2022-04-18
      回复
    • tong酱
      tong酱
      2022-06-17回复。。。。
      我也遇到这个问题了,是因为vue项目的路由使用了#
      2022-06-17
      回复
  • 小晴儿.
    小晴儿.
    2022-03-04

    请问小程序跳转项目目录内的html页面怎么办捏?

    2022-03-04
    赞同
    回复 3
    • 游戏人生
      游戏人生
      2022-03-04
      打开一个web-view页面A,传参,A页面读取参数给web-view赋值
      2022-03-04
      回复
    • 云の彼端
      云の彼端
      2022-04-14回复游戏人生
      你好,我在前一个页面存了一个currentUrl, 想在下一个页面的webview里赋值给src;但是目前直接在图2写到src,或者在js里的onLoad周期赋值给变量src(图3,此时图2的代码为src="{{src}}")都不行,页面是空白的,第一次开发小程序,请问什么问题,怎么解决?
      2022-04-14
      回复
    • 云の彼端
      云の彼端
      2022-04-14回复云の彼端
      是setData的问题, 已解决。
      2022-04-14
      回复
  • 茜茜😊
    茜茜😊
    2022-01-11

    请问楼主 有没有什么办法可以使页面同时包含原生组件和webview呢

    2022-01-11
    赞同
    回复 1
    • 游戏人生
      游戏人生
      2022-01-11
      可以写,但显示不了。。。如果是展示类的原生组件是没有意义的,功能类的是可以的,比如行为统计,状态捕捉等
      2022-01-11
      回复

正在加载...

登录 后发表内容