- [填坑手册]小程序web-view组件实战与踩坑
[图片] 首先,根据官网文档可以知道 只有非个人 的小程序才可以使用web-view组件,如果你的个人开发者,可以跳过这篇文章。 [图片] 一、使用web-view以及它的好处 1、己方账号(第三方)与小程序openId/UnionId的关联绑定,实现免登陆 比如你是某门户网站S,你要识别自己小程序上的用户与网站用户的关系,你可以通过三种方法绑定关系,公众号,小程序源生,小程序web-view内嵌跳转三种方法 2、内嵌H5的富文本,减少重复开发 比如你是门户网站,社区,以往有大量的新闻和帖子,里面带了各种css样式的富文本,小程序源生是无法直接读取的,需要大量转化,这时候直接内嵌这些H5新闻,大大降低开发成本 3、热更新,减少发布审核 某些需要经常更新的内容、公告、活动页,内嵌H5可以减少频繁提交小程序审核 二、小程序功能赋权 为H5提供各种小程序才有的功能,比如录音,扫一扫等。 注意事项 多场景判断,建议使用官方API: wx.miniProgram.getEnv H5唤醒一些小程序API有一定的延时,0.3~1秒 请调用小程序专用的JSSDK,同一个jssdk,但是webview的功能收到限制,和之前微信打开H5有所不同 小程序自动获取加载H5的title H5中iframe的url必须也是业务域名 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> [代码] 注意事项 那些H5控制小程序的跳转路径必须是“/”开头,如 “/pages/xxx/xxx”,且路径必须在app.json里有,地址错误的话,有时不报错。 postMessage的json必须是data开始,不然接收不到数据。 [图片] 四、bindmessage接收到消息有3个重要特性(重点) 接收可以是H5之前几分钟前发送postMessage,不一定是即刻发出的。 之前发出的 postMessage的DATA信息会累加,当触发bindmessage接收的时候是一个数组。 [图片] 当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还是非常实用的组件,且用且珍惜~ 往期回顾: 小程序自定义头部导航栏“完美”解决方案 小程序Canvas生成海报(一) 小程序新版订阅消息+云开发实战与跳坑
2021-09-13 - canvas生成海报图、分享
首先话不多说元素样式走起来 canvas宽高由js变量动态定义 html <canvas class=‘canvas’ canvas-id=“shareCanvas” style=“width:{{canvasWidth}}px;height:{{canvasHeight}}px”></canvas> css .canvas{ margin: 0 auto; letter-spacing: 2rpx; //画布上文字间距 我实在不知道canvas api怎么控制字间距 margin-top: 10%; } 然后绘制canvas代码 canvasImg:function(){ [代码]var that = this; wx.showLoading({ title: '图片正在生成' }); //拿到用户名称和用户头像 name ,img var name = app.header.userInfo.nickName; var img = app.header.userInfo.avatarUrl.replace("http:", "https:"); //请求后台接口拿到小程序码临时url //这里是我们后台根据我传递的页面路径和标识获取对应小程序的小程序码 返回一个图片临时缓存的url wx.request({ url: app.data.proxy + '/miniprogram/getUnlimited', data: { type: app.data.pdd, page:'pages/index/index' }, success(res) { var image = res.data.result; //拿到临时url 使用getImageInfo缓存到本地 wx.getImageInfo({ src:image, success(res){ //liload 小程序码本地缓存地址 var liload = res; //获取用户设备宽高 wx.getImageInfo({ src: img, success(res) { var width,height; wx.getSystemInfo({ success(res) { width = res.screenWidth * 0.6; height = Math.round(width * 1066 / 600); that.setData({ canvasWidth: width, canvasHeight: height }); } }); var x = width/750; //设置相对canvas自适应根元素大小 const ctx = wx.createCanvasContext('shareCanvas'); ctx.drawImage('../img/pinduoduo.jpg', 0, 0, 500*x, 812*x); ctx.save(); ctx.setTextAlign('center'); // 文字居中 ctx.setFillStyle('#fff'); // 文字颜色:黑色 ctx.setFontSize(16); // 文字字号 ctx.fillText(name, 250*x, 250*x); //名字 ctx.setFontSize(14); // 文字字号 ctx.fillText('邀请你使用【拼拼宝盒】', 250*x, 300*x); ctx.save(); //圆形头像框 ctx.setStrokeStyle('rgba(0,0,0,.2)'); ctx.arc(250 * x, 140 * x, 60 * x, 0, 2 * Math.PI); ctx.setStrokeStyle('rgba(0,0,0,.2)'); ctx.arc(250 * x, 460 * x, 120 * x, 0, 2 * Math.PI); ctx.fill('#fff'); //小程序码 ctx.clip(); ctx.drawImage(liload.path, 150*x, 360*x, 200*x, 200*x); //头像 ctx.clip(); ctx.drawImage(res.path, 190*x, 80*x, 120*x, 120*x); ctx.save(); ctx.stroke(); ctx.draw(); wx.hideLoading(); } }); } }) } }); [代码] } 绘制完成 [图片] 保存事件 这里首先用getSetting检测用户有没有开启相册权限 有的话直接保存 没有的话弹到权限页面让用户授权 btnTap:function () { [代码]var that = this; wx.showLoading({ title: '正在保存', mask: true, }); wx.getSetting({ success(res) { if (res.authSetting['scope.writePhotosAlbum']) { that.saveImg(); } else if (res.authSetting['scope.writePhotosAlbum'] === undefined) { wx.authorize({ scope: 'scope.writePhotosAlbum', success() { that.saveImg(); }, fail() { wx.showToast({ title: '您没有授权,无法保存到相册', icon: 'none' }) } }) } else { wx.openSetting({ success(res) { if (res.authSetting['scope.writePhotosAlbum']) { that.saveImg(); } else { wx.showToast({ title: '您没有授权,无法保存到相册', icon: 'none' }) } } }) } } }) [代码] } 用户有授权调用保存图片API 保存图片到手机 saveImg:function(){ [代码] wx.canvasToTempFilePath({ canvasId: 'shareCanvas', success: function (res) { wx.hideLoading(); var tempFilePath = res.tempFilePath; wx.saveImageToPhotosAlbum({ filePath: tempFilePath, success(res) { wx.showModal({ content: '图片已保存到相册,赶紧晒一下吧~', showCancel: false, confirmText: '好的', confirmColor: '#333', success: function (res) { if (res.confirm) { var arr = []; arr.push(tempFilePath); //保存后全屏显示 wx.previewImage({ urls: arr, current: arr }); } }, fail: function (res) { } }) }, fail: function (res) { wx.showToast({ title: '没有相册权限', icon: 'none', duration: 2000 }); } }) } }); [代码] } 好了 就这么多了 第一次发帖 有不足之处望各路大佬见谅、指出不胜感激 附代码片段:https://developers.weixin.qq.com/s/8Z8oXbm17ojh
2020-07-28