- 复制任意微信小程序页面路径
以下以微信小程序“虎牙直播”为例,演示如何复制微信小程序页面的路径。 1.进入小程序的“关于虎牙直播”页面 [图片] 2.点击右上角的“…”进入“更多资料”页面 [图片] [图片] [图片] 3.复制AppID:wx74767bf0b684f7d3 4.进入小程序后台输入appid并搜索,然后点下一步 [图片] 5.鼠标移动到“获取更多页面路径”,在弹出窗口输入当前登陆的小程序的任意开发者微信号,然后点击开启,出现顶部的“开启入口成功”就可以使用手机访问“虎牙直播”任意页面进行复制了 [图片] 6.某个直播间的页面路径:pages/main/liveRoom/index.html?anchorUid=1678113423&source=search[图片] PS:复制出来的页面路径在小程序里使用的时候记得删除 .html 才能正常访问。
2020-01-16 - 如何关注公众号以后自动推送小程序?
如何关注公众号以后自动推送小程序? 这个问题是不是觉得没什么难度?打开配置界面一看你就傻眼了。 [图片] 怎么自动回复里没有跳转小程序选项?自定义菜单里面是有的呀!:( [图片] 遇到困难先不要慌,办法总是有的! 不过要做一点点准备工作,首先绑定要跳转的小程序,然后准备好小程序的APPID和跳转路径。 然后,一行代码搞定: <a data-miniprogram-appid="小程序APPID" data-miniprogram-path="跳转路径">点我跳转到小程序</a> 上面准备的小程序APPID和跳转路径编辑一下即可。 <a data-miniprogram-appid="wx3fa5ddf638c664d8" data-miniprogram-path="page/tabBar/index/index">点我跳转到小程序</a> [图片] [图片] 想体验效果,搜索:来一间 公众号体验。关键词自动回复也可以用这个方法配置哦! [图片] 补充一点: 如何获取小程序页面路径的方法:https://developers.weixin.qq.com/community/develop/article/doc/0008627017cf104da879c3dd25b813
2020-07-14 - wx.getAccountInfoSync() envVersion 审核版是那个值?
wx.getAccountInfoSync() envVersion 审核版是那个值?
2021-02-25 - 微信小程序答题页——swiper渲染优化及swiper分页实现
前言 swiper的加载太多问题,网上资料好像没有一个特别明确的,就拿这个答题页,来讲讲我的解决方案 这里实现了如下功能和细节: 保证swiper-item的数量固定,加载大量数据时,大大优化渲染效率记录上次的位置,页面初次加载不一定非得是第一页,可以是任何页答题卡选择某一index回来以后的数据替换,并去掉swiper切换动画,提升交互体验示例动图 [图片] 截图 [图片] [图片] 问题原因 当swiper-item数量很多的时候,会出现性能问题 我实现了一个答题小程序,在一次性加载100个swipe-item的时候,低端手机页面渲染时间达到了2000多ms 也就是说在进入答题页的时候,会卡顿2秒多去加载这100个swiper-item 思考问题 那我们能不能让他先加载一部分,然后滑动以后再去改变item的数据,让swiper一直保持一定量的swiper-item? 注意到官方文档有这么两个属性可以利用,我们可以开启衔接滑动,然后再bindchange方法中去修改data [图片] 1、保证swiper-item的数量固定,加载大量数据时,优化渲染效率 假设我们请求到的数据的为list,实际渲染的数据为swiperList 我们现在给他就固定3个swiper-item,前后滑动的时候去替换数据 正向滑动的时候去替换滑动后的下一页数据,反向滑动的时候去替换滑动后的上一页数据 当我们知道了要替换的条件,我们便可以去替换数据了 但是我们应该考虑到临界值的问题,如果当前页是list第一项和最后一项该怎么办,向左向右滑是不是得禁止啊 这边是判断没数据会让它再弹回去 2、记录上次的位置,页面初次加载不一定非得是第一页,可以是任何页 有很多时候,我们是从某一项直接进来的,比如说上次答题答到了第五题,我这次进来要直接做第六题 那么我们需要去初始化这个swiperList,让它当前页、上一页、下一页都有数据 3、答题卡选择某一index回来以后的数据替换,并去掉swiper切换动画,提升交互体验 从答题卡选择index,那就不仅仅是滑动上下页了,它可以跳转到任何页,所以也采用类似初始化swiperList的方法 swiper切换动画我这边是默认250ms,但是发现有时候从答题卡点击回来,你在答题卡点击的下一项不知道会从左还是从右滑过来 体验真的很差,一开始不知道怎么禁掉动画,其实在跳转到答题卡页的时候把duration设为0就可以了 然后在答题卡页的unload方法中恢复 关键点: 在固定3个swiper-item的同时,要保证我们可以有办法来替代微信自带swiper的current属性和change方法 swiper-limited-load使用方法及说明: 将components中的swiper-limited-load复制到您的项目中在需要的页面引用此组件,并且创建自己的自定义组件item-view在初始化数据时,为你的list的每一项指定index属性具体可以参照项目目录start-swiper-limited-load中的用法说明:其它属性和swiper无异,你们可以自己单独添加你们需要的属性总结 一开始很头疼,为什么微信小程序提供的这个swiper,没去考虑这方面 然后在网上和社区找也没有一个特别好的解决方案。 后来想想,遇到需求就静下来解决吧。 项目地址:https://github.com/pengboboer/swiper-limited-load 如果错误,欢迎指出。 如有新的需求也可以提出来,如果有时间的话,我会帮你们完善。 如果能帮到你们,记得给一个star,谢谢。 ---补充 有很多朋友在评论区提到了分页的需求,抽时间写了一个分页的Demo和大家分享一下。 还是以答题为例,比如我们一共有500条数据,一页20条,可能需要如下功能,乍一看不就加了个分页,挺简单的,其实实现起来挺麻烦的,下面说一下思路和一些需要特别注意的点: 1、从其他页面跳转到答题页时,不光只能默认在第一题,可以是任意一题,比如第80题。 跳转到任意一题,那么需要我们根据index算出该数据在第几页,然后需要请求该页数据,最后显示对应的index。我的思路更注重用户体验,不可能是上滑或者下滑才开始去请求数据,一定是要用户滑动前提前请求好数据。所以起码要保证左右两侧在初始化那一刻都有数据。如果此题和它的上一题下一题都在同一页,那么我们只需要请求一页数据(第15题,那么只需请求第1页数据)。如果此题和它的上一题或者下一题不在同一页,那么我们可能需要请求两页数据。(第20题,那么需要请求第1页和第2页数据) 2、左滑、右滑没数据时,都可以加载新数据。直到滑到第一题或者最后一题。 如果我们初始化时是第24题,那么我们左滑到第21题时,就应该去请求第一页的数据。那么用户在看完21题时,再滑到20题,可能就根本不会感知到通过网络请求了数据。但是如果用户此刻滑动特别快:滑到21题时请求了网络,请求还没成功,就又向左滑了。那么我们需要限制用户的滑动,给用户一个提示:数据正在加载中。 3、从答题卡点击任意一题可以跳转到相应的题目,并且左右滑动显示正常数据 比如我们初始化是跳转到了第80题,不一会点击答题卡又要跳转到200题,一会又跳转到150题。各种无序操作,你也不知道用户要往哪里点。 一开始是想着维护一个主list,点到哪道题往list中添加这道题所在的当页的数据,但是还得判断这一页或者左滑右滑请求新一页的数据得往list的哪个位置添加。这来回来去乱七八糟的判断就很麻烦了,很容易出bug。而且list长度太长了以后insert的性能也不好。 后来就去想,要不答题卡点击任意一题都清空旧的list,然后请求新的数据,左右滑动没数据了再请求新的数据呗。但是这样很浪费资源,并且用户体验也不好,用户已经从第1题答到第200题了,这时用户从答题卡选择了一个25题,还得重新请求网络。而且200道题的数据都没了,那再选个26题,再重新请求网络?网络有延时不说,还浪费资源。 最后转念一想,这时候就需要弄一个缓存了。所以最终的解决方法就出来了:我们维护一个map,在网络请求成功后,在map中保存对应页的数据,同时我们维护一个主list来显示对应的题目。当我们在答题卡选择某一题目,就清空list,然后判断map中有没有该页的数据,如果有就直接拿来,没有就再去网络请求。这个处理方式,写法相对来说简单,不需要乱七八糟的判断,也不浪费资源,用户体验也很不错。 总结 以上就是一些思路和要注意的地方。这个Demo断断续续花了好几天时间写出来的。可能我说的比较啰嗦比较细,只是想让需要用到这个分页Demo的同学能理解我是如何实现的。 如果觉得能帮到你,记得给一个star,谢谢。同时如果这个demo有bug或者你们有新想法,欢迎提出来。
2021-01-07 - 小程序 createInnerAudioContext 无法播放https://音频源的问题?
如题,附下面代码, 如果音频源为https调试工具可以播放音乐,但是手机调试,体验版。不能播放(测试手机 安卓11 微信版本 8.0.6) 错误提示 (音频源文件相同) {errCode: 10001, errMsg: "errCode:504, err:error player to stop"} {errCode: 10004, errMsg: "errCode:55, err:unknow format"} 如果音频源为https调试工具可以播放音乐,手机可以播放(测试手机 安卓11 微信版本 8.0.6) 下面是代码段 let audiocontent = wx.createInnerAudioContext() audiocontent.src = 'https://a.com/1.mp3' //无法播放音乐 audiocontent.src = 'http://a.com/1.mp3' //可以播放 audiocontent.play();
2021-06-05 - input聚焦弹出键盘时, 防止自定义导航上移的一种解决方法
前提 在开发小程序的过程中,会经常使用到[代码]input[代码]组件,其聚焦的时候,会在必要时自动上移整个页面以便弹起的键盘不回遮住[代码]input[代码]组件 但是当页面应用自定义导航时,聚焦时会把自定义导航也上移,而这就不符合我们的预期,我们希望的是导航栏始终固定在顶部,下面的内容上移即可!参见该帖子 为了解决这个问题,我们只好自己来处理页面上移的事情了! 准备工作 首先我们需要先关闭掉输入框自动上移页面的功能 [代码]<input type="text" adjust-position="{{false}}" /> [代码] 接下来我们就要自己处理页面上移的工作了 为了让除了导航栏的区域整体上移, 我们需要先可以定义一个值(top)来表示上移距离 [代码]// index.js Page({ data: { top: 0 } }) [代码] 其次 需要固定好页面的结构, 如下: 我们要做的便是只上移[代码].cointainer[代码]这个组件, 故使用[代码]top: -{{top}}px[代码]来表示内容上移 [代码]// index.wxml <mp-navigation-bar background="#d8d8d8" title="导航栏标题"></mp-navigation-bar> <view class="container" style="position: relative; top: -{{top}}px"> 内容区域 </view> [代码] 计算上移距离 我们先思考什么情况下, 页面需要上移? 显然是[代码]input[代码]距离底部的距离小于弹出的键盘高度的时候需要上移, 而上移的距离便是距离底部的距离与键盘高度的差 那么只需要知道这两个值便可实现该功能了. 键盘高度 翻阅input的文档, 我们发现监听[代码]bindfocus[代码]或者[代码]bindkeyboardheightchange[代码]事件都可以获取到键盘的高度 [代码]// index.wxml # index.wxml <input id="input1" type="text" adjust-position="{{false}}" bindfocus="onHandleFocus" bindblur="onBlur" /> // index.js onHandleFocus (e) { console.log('focus', e) const keyboradHeight = e.detail.height } [代码] 距离底部的距离 首先我们需要货值输入框的位置, 这里可以使用[代码]SelectorQuery[代码]来获取输入框的位置 [代码] # index.js onHandleFocus (e) { console.log('focus', e) const keyboradHeight = e.detail.height const id = e.currentTarget.id this.createSelectorQuery() .select(`#${id}`) .boundingClientRect(rect => { console.log('==> rect', rect) }).exec() } [代码] 获取到的rect对象同DOM的[代码]getBoundingClientRect[代码], 然后我们再观察这张图片: [图片] 显然要计算输入框距离底部的距离只需用显示高度减去bottom即可 页面的显示高度可以用如下方法获得 [代码]const { windowHeight } = wx.getSystemInfoSync() [代码] 最后我们上诉思路整理成对应代码 [代码] # index.js onHandleFocus (e) { console.log('focus', e) const keyboradHeight = e.detail.height const id = e.currentTarget.id this.createSelectorQuery() .select(`#${id}`) .boundingClientRect(rect => { console.log('==> rect', rect) const { windowHeight } = wx.getSystemInfoSync() const bottom = windowHeight - rect.bottom if (bottom > keyboradHeight) { // 距离足够, 不需要上移 return } this.setData({ top: keyboradHeight - bottom }) }).exec() } [代码] 完整代码见该代码片段 尾声 该方法虽然能够解决标题所述的问题,当也存有其他问题: 页面结构必须固定结构(分为标题-内容两大块) 所有的[代码]input[代码]都必须加上[代码]id[代码],否则[代码]createSelectorQuery[代码]选择器没法找到对应的[代码]input[代码],且必须监听[代码]focus[代码]和[代码]blur[代码]方法。 最外层的内容[代码]view[代码]的[代码]top[代码]样式被占用 PS: 计算上移距离的这部分代码可以写成一个[代码]behavior[代码]方便其他页面直接引入
2021-04-22 - 教你怎么监听小程序的返回键
更新:2020年7月28日08:51:11 基础库2.12.0起,可以调用wx.enableAlertBeforeUnload监听原生右上角返回、物理返回以及wx.navigateBack时弹框提示 AIP详情请看: https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.enableAlertBeforeUnload.html //======================================== 怎么监听小程序的返回键? 应该有很多人想要监听用户的这个动作吧,但是很遗憾,小程序不会给你这个API的,那是不是就没辙了? 幸好我们还可以自定义导航栏,这样一来我们就可以监听用户的这一动作了。 什么?这你已经知道啦? 那好咱们就不说自定义导航栏的返回监听了,说一下物理返回和左滑?右滑?(不管了,反正是滑)返回上一页怎么监听。 监听物理返回 首先说一下这个监听方法的缺点,虽说是监听,但是还是无法真正意义上的监听并拦截来阻止页面跳转,页面还是会返回上一页,而后重新载入刚刚的页面,如果这不是你想要的,那可以不用往下看了 其次说一下用到什么东西: wx.onAppRoute、wx.showModal 最后是一些主要代码: 重写wx.showModal,主要是加个confirmStay参数和使wx.showModal Promise化 [代码]const { showModal } = wx; Object.defineProperty(wx, 'showModal', { configurable: false, // 是否可以配置 enumerable: false, // 是否可迭代 writable: false, // 是否可重写 value(...param) { return new Promise(function (rs, rj) { let { success, fail, complete, confirmStay } = param[0] param[0].success = (res) => { res.navBack = (res.confirm && !confirmStay) || (res.cancel && confirmStay) wx.setStorageSync('showBackModal', !res.navBack) success && success(res) rs(res) } param[0].fail = (res) => { fail && fail(res) rj(res) } param[0].complete = (res) => { complete && complete(res) (res.confirm || res.cancel) ? rs(res) : rj(res) } return showModal.apply(this, param); // 原样移交函数参数和this }.bind(this)) } }); [代码] 使用wx.onAppRoute实现返回原来的页面 [代码]wx.onAppRoute(function (res) { var a = getApp(), ps = getCurrentPages(), t = ps[ps.length - 1], b = a && a.globalData && a.globalData.pageBeforeBacks || {}, c = a && a.globalData && a.globalData.lastPage || {} if (res.openType == 'navigateBack') { var showBackModal = wx.getStorageSync('showBackModal') if (c.route && showBackModal && typeof b[c.route] == 'function') { wx.navigateTo({ url: '/' + c.route + '?useCache=1', }) b[c.route]().then(res => { if (res.navBack){ a.globalData.pageBeforeBacks = {} wx.navigateBack({ delta: 1 }) } }) } } else if (res.openType == 'navigateTo' || res.openType == 'redirectTo') { if (!a.hasOwnProperty('globalData')) a.globalData = {} if (!a.globalData.hasOwnProperty('lastPage')) a.globalData.lastPage = {} if (!a.globalData.hasOwnProperty('pageBeforeBacks')) a.globalData.pageBeforeBacks = {} if (ps.length >= 2 && t.onBeforeBack && typeof t.onBeforeBack == 'function') { let { onUnload } = t wx.setStorageSync('showBackModal', !0) t.onUnload = function () { a.globalData.lastPage = { route: t.route, data: t.data } onUnload() } } t.onBeforeBack && typeof t.onBeforeBack == 'function' && (a.globalData.pageBeforeBacks[t.route] = t.onBeforeBack) } }) [代码] 改造Page [代码]const myPage = Page Page = function(e){ let { onLoad, onShow, onUnload } = e e.onLoad = (() => { return function (res) { this.app = getApp() this.app.globalData = this.app.globalData || {} let reinit = () => { if (this.app.globalData.lastPage && this.app.globalData.lastPage.route == this.route) { this.app.globalData.lastPage.data && this.setData(this.app.globalData.lastPage.data) Object.assign(this, this.app.globalData.lastPage.syncProps || {}) } } this.useCache = res.useCache res.useCache ? reinit() : (onLoad && onLoad.call(this, res)) } })() e.onShow = (() => { return function (res) { !this.useCache && onShow && onShow.call(this, res) } })() e.onUnload = (() => { return function (res) { this.app.globalData = Object.assign(this.app.globalData || {}, { lastPage: this }) onUnload && onUnload.call(this, res) } })() return myPage.call(this, e) } [代码] 在需要监听的页面加个onBeforeBack方法,方法返回Promise化的wx.showModal [代码]onBeforeBack: function () { return wx.showModal({ title: '提示', content: '信息尚未保存,确定要返回吗?', confirmStay: !1 //结合content意思,点击确定按钮,是否留在原来页面,confirmStay默认false }) } [代码] 运行测试,Oj8K 是不是很简单,马上去试试水吧,效果图就不放了,静态图也看不出效果,动态图懒得弄,想看效果的自己运行代码片段吧 代码片段 https://developers.weixin.qq.com/s/hc2tyrmw79hg
2020-07-28