- wx.canvasToTempFilePath fileType:“jpg” 。结果为png?
[图片] 2D画布生成图片返回的链接,使用wx.getImageInfo 读取的type为png,,保存下来的图片位深32位。不应该是jpg,位深24的吗?
2020-05-27 - 高阶性能渲染-wxs
我们永远没有资格说放弃,因为这是属于我们的年华,应该开出耀眼的繁花。 这里主要讲解两点使用方式 wxs --> 数据处理使用 wxs --> 拖拽使用 wxs介绍 1.先看看官方如何介绍的 ,如下 点我可以查看更多官方文档地址 WXS 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行。 WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致。 WXS 的运行环境和其他 JavaScript 代码是隔离的,WXS 中不能调用其他 JavaScript 文件中定义的函数,也不能调用小程序提供的API。 WXS 函数不能作为组件的事件回调。 由于运行环境的差异,在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异。 总的来说,我主要看中它快和方便 (有种在wxml写函数的感觉),并且处理函数内容后渲染不需要去调用setData,可以节省在请求数据返回后写大量的逻辑函数或者遍历方法去处理事务,所以我才拿出来讲解。 wxs数据处理使用 使用我习惯现在utils文件夹里创建一个common.wxs,然后在使用的wxml引入该文件。具体使用也很简单,如下 在你定义的common.wxs文件里,写你需要处理的函数,然后使用export导出 [代码] var getMax = function(array) { var max = undefined; for (var i = 0; i < array.length; ++i) { max = max === undefined ? array[i] : (max >= array[i] ? max : array[i]); } return max; } module.exports = { getMax: getMax }; [代码] 在.wxml文件需要的地方引入该.wxs文件,其中<wxs>标签包含2个重要属性,[代码]module[代码]和[代码]src[代码]<br> module表示你要导出wxs的方法集合,在wxml里面可以使用该方法名去使用具体的函数<br> src表示你.wxs路径位置引入,代码如下 [代码]<wxs module="common" src="../../utils/common.wxs"></wxs> <view> <text>{{common.getMax(arrNumber)}}</text> </view> [代码] 上面代码里[代码]arrNumber[代码]是你页面.js文件里面定义的数据 [代码]data: { arrNumber: [1,2,9,2,1,5,7] } [代码] 就是如此简单,你已经学会了使用wxs处理数据了,接下来我们来点难的,使用wxs做一个可以随便拖动又不影响小程序性能的手势拖拽事件 wxs拖拽使用 你是否还在使用setData控制元素?为什么不能频繁使用setData,点我查看详情然后通过输出手势坐标来移动元素具体位置?如果是建议你该换个方法了,推荐使用wxs,让你小程序性能上一个档次。 解决思路如下: 我们先在页面的.wxml文件书写初始化的样式内容; 给[代码]view[代码]标签绑定手势事件,其中[代码]touchmove[代码]我使用了阻止冒泡事件绑定是为了防止在苹果机中,元素移动会带着屏幕一起移动,导致滑动手势突然中断不流畅, [代码]clickLive[代码]事件我也用了阻止冒泡事件是为了触发子元素的事件防止点击被父元素拦截而使用,代码如下: [代码]<wxs module="comm" src="../../utils/common.wxs"></wxs> <view class="enterLive liveMove" data-maxWidth="{{windowWidth}}" data-maxHeight="{{windowHeight}}" bind:touchstart="{{comm.liveTouchmove}}" catch:touchmove="{{comm.liveTouchmove}}" bind:touchend="{{comm.liveTouchmove}}"> <view class="live-block" catch:tap="{{comm.clickLive}}"> <image class="liveEnter-img" mode="aspectFit" src="https://img0.baidu.com/it/u=401284325,23907343&fm=26&fmt=auto&gp=0.jpg" /> </view> </view> [代码] 我们发现上面的代码有[代码]windowWidth,windowHeight[代码]两个参数,这是在页面的.js中,是计算当前页面的宽高,用于防止滑块滑出视野范围内,导致无法滑动回来,其中下面代码[代码]getApp().globalData.systemInfo[代码]是读取全局文件[代码]app.js[代码]里面拿值的,那里我有获取系统参数设为全局保存, 而[代码]bindEnter[代码]事件是用于待会在[代码].wxs[代码]里面可以触发.js文件内函数示例 [代码]data: { windowWidth: 375, windowHeight: 667, }, ready: function() { let systemInfo = getApp().globalData.systemInfo; let width = 150 * systemInfo.windowWidth / 750; let height = 150 * systemInfo.windowWidth / 750; if (systemInfo) { this.setData({ windowWidth: systemInfo.windowWidth - parseInt(width), windowHeight: systemInfo.windowHeight - parseInt(height) }) } }, bindEnter(e) { wx.showToast({ title: '你点击到我啦~', icon: 'none' }) }, [代码] 接下来我们将书写.wxs文件,处理手势输出内容,使页面的滑块可以平静的滑动; 认真看的同学会发现页面的[代码]touchstart,touchmove,touchend[代码]事件我都是绑定同一个函数[代码]liveTouchmove[代码]这里是我想节约函数名称,统一使用一个函数,然后在输出的回调里面判断当前是什么手势 这里的滑块滑动逻辑是:当输出是touchstart手势时,我们记住当前滑块的[代码]starLeft,starTop[代码]值及坐标[代码]starX,starY[代码]值 当我们判断当前是[代码]touchmove[代码]手势时,我们就用当前的x,y坐标值减去开始starX和starY坐标值,得到一个差值[代码]diffX,diffY[代码] 然后我们使用这个[代码]diffX,diffY[代码]差值分别加上滑块刚开始的[代码]starLeft,starTop[代码]值,即可得到我们滑块当前移动的位置 最后我们通过条件判断当前是否超出屏幕即可,我这里做多一步,就是滑块永远停留左右两边,所以要多算一次滑块停留是偏离那一边,在通过[代码]ownerInstance.selectComponent('.liveMove').setStyle[代码]可以给页面元素添加行内样式。 滑动滑动逻辑已经讲完了,就是这么简单 如果你想通过[代码].wxs[代码]函数触发[代码].js[代码]文件内的函数,这里有提供[代码]ownerInstance.callMethod("bindEnter")[代码]方法给你触发.js里面的函数,其中[代码]ownerInstance[代码]是绑定页面函数的第二个回调参数,[代码]callMethod[代码]是官方提供的一个方法,[代码]bindEnter[代码]是.js文件里自己命名的函数方法名称,整体代码如下:更多wxs内置方法,请查看官方文档 [代码]/** * 滑块计算位置 */ var starLeft = 0; var starTop = 0; var starX = 0; var starY = 0; function liveTouchmove(event, ownerInstance) { // console.log(JSON.stringify(event)) // console.log(JSON.stringify(ownerInstance)) var left = 0, top = 0; var diffX = 0, diffY = 0; if(event.type === 'touchstart') { starLeft = event.currentTarget.offsetLeft; starTop = event.currentTarget.offsetTop; starX = event.changedTouches[0].clientX; starY = event.changedTouches[0].clientY; left = starLeft; top = starTop; } else { diffX = event.changedTouches[0].clientX - starX; diffY = event.changedTouches[0].clientY - starY; left = starLeft + diffX; top = starTop + diffY; var maxWidth = event.currentTarget.dataset.maxwidth; var maxHeight = event.currentTarget.dataset.maxheight; if (left > maxWidth) { left = maxWidth; } if (top > maxHeight) { top = maxHeight; } if (left <= 0) { left = 0; } if (top <= 0) { top = 0; } } if (event.type === 'touchend') { if (maxWidth / 2 < left) { left = "calc(100% - 3% - 152rpx)"; } if (maxWidth / 2 > left) { left = '3%'; } } else { left = left + 'px'; } var instance = ownerInstance.selectComponent('.liveMove'); // 返回组件的实例 instance.setStyle({ left: left, top: top +'px', }); } /** * 点击直播入口 * @param */ function clickLive (event, ownerInstance) { ownerInstance.callMethod("bindEnter"); } module.exports = { liveTouchmove: liveTouchmove, clickLive: clickLive, }; [代码] 总结 wxs确实可以解决我们一些性能问题,和wxml函数调用方便,但是我们也要注意几个问题 目前还不支持原生组件的事件、input和textarea组件的 bindinput 事件 1.02.1901170及以后版本的开发者工具上支持交互动画,最低版本基础库是2.4.4 目前在WXS函数里面仅支持console.log方式打日志定位问题,注意连续的重复日志会被过滤掉。 wxs有自己的语法,我理解为不支持ES6及以上语法更多wxs语法可以查看官方文档 以上内容,包括之前写的文章内容,最终会上传到我的gitee里面,请留意。 文章创作不易,喜欢的记得点赞 本文同步掘金号文章 喜欢的记得去点个赞哦
2021-07-11 - 微信朋友圈选图效果
中秋快乐,帮社区里的小伙伴写的选图效果,仿造的微信朋友圈选图,长按拖动排序主要是用交互监听来实现的。还有几个需要处理的地方。另外在真机上的动画速度总感觉快那么一丢丢。没做预览图,详情见代码片段咯。安卓机效果没试过。。 今天是9月23,这两天接受定制改动~ 第一次发经验分享。。轻点喷。。 哦,对了,这里 wx.createSelectorQuery 有个bug。。如果选择的基础库版本在2.0.9以上,第一次打开开发者工具,要先直接点一次编译,不然会出错。。真机上没问题 代码片段:wechatide://minicode/RFLmzDmL7I2a 有小伙伴反馈,在片段上面增加内容会乱位,是因为没计算顶部偏移量,方便懒人,完善了下 新的片段:wechatide://minicode/fOTEM3mI7l3B 终于拿到安卓机器试了,果然卡得很。。要控制频率。这很尴尬,太频繁的话,安卓会卡,太不频繁呢,刚开始移动那阵子会卡。。有同学反馈,说点快了会出问题,于是又加了点击频率的限制 现在的代码片段:wechatide://minicode/xBDdCom17R3c(要重新拿安卓机测试了再看看。。) 附上gif: [图片]
2018-10-24 - 滑块拖动排序 【恋爱小清单开发总结】
分享一下滑块拖动排序的案例,其实主要的关键点在于判断当前长按的坐标点跟滑块中心的位置关系,这次直接分享代码片段了。有兴趣的有小伙伴可以打开瞧一瞧。 https://developers.weixin.qq.com/s/qKcgIVmL7Qj7 也可以打开恋爱小清单小程序 -> 我-> 纪念日 页面效果图: [图片]
2021-09-09 - 如何监听小程序中的手势事件(缩放、双击、长按、滑动、拖拽)
mina-touch [图片] [代码]mina-touch[代码],一个方便、轻量的 小程序 手势事件监听库 事件库部分逻辑参考[代码]alloyFinger[代码],在此做出声明和感谢 change log: 2019.03.10 优化监听和绘制逻辑,动画不卡顿 2019.03.12 修复第二次之后缩放闪烁的 bug,pinch 添加 singleZoom 参数 2020.12.13 更名 mina-touch 2020.12.27 上传 npm 库;优化使用方式;优化 README 支持的事件 支持 pinch 缩放 支持 rotate 旋转 支持 pressMove 拖拽 支持 doubleTap 双击 支持 swipe 滑动 支持 longTap 长按 支持 tap 按 支持 singleTap 单击 扫码体验 [图片] demo 展示 demo1:监听 pressMove 拖拽 手势 查看 demo 代码 [图片] [图片] demo2: 监听 pinch 缩放 和 rotate 旋转 手势 (已优化动画卡顿 bug) 查看 demo 代码 [图片] [图片] demo3: 测试监听双击事件 查看 demo 代码 [图片] [图片] demo4: 测试监听长按事件 查看 demo 代码 [图片] [图片] demo 代码 demo 代码地址 mina-tools-client/mina-touch 使用方法 大致可以分为 4 步: npm 安装 mina-touch,开发工具构建 npm 引入 mina-touch onload 实例化 mina-touch wxml 绑定实例 命令行 [代码]npm install mina-touch[代码] 安装完成后,开发工具构建 npm *.js [代码]import MinaTouch from 'mina-touch'; // 1. 引入mina-touch Page({ onLoad: function (options) { // 2. onload实例化mina-touch //会创建this.touch1指向实例对象 new MinaTouch(this, 'touch1', { // 监听事件的回调:multipointStart,doubleTap,longTap,pinch,pressMove,swipe等等 // 具体使用和参数请查看github-README(底部有github地址 }); }, }); [代码] NOTE: 多类型事件监听触发 setData 时,建议把数据合并,在 touchMove 中一起进行 setData ,以减少短时内多次 setData 引起的动画延迟和卡顿(参考 demo2) *.wxml 在 view 上绑定事件并对应: [代码]<view catchtouchstart="touch1.start" catchtouchmove="touch1.move" catchtouchend="touch1.end" catchtouchcancel="touch1.cancel" > </view> <!-- touchstart -> 实例对象名.start touchmove -> 实例对象名.move touchend -> 实例对象名.end touchcancel -> 实例对象名.cancel --> [代码] NOTE: 如果不影响业务,建议使用 catch 捕获事件,否则易造成监听动画卡顿(参考 demo2) 以上简单几步即可使用 mina-touch 手势库 😊😊😊 具体使用和参数请查看Github https://github.com/Yrobot/mina-touch 如果喜欢mina-touch的话,记得在github点个start哦!🌟🌟🌟
2021-06-24 - 使用Vant weapp组件库,van-image如何引入本地图片?
使用Vant weapp组件库,van-image如何引入本地图片?怎么引入都报错找不到图片呢?
2020-07-03 - iPhone 安全区适配,小黑条适配标准解决方案
老规矩,先上代码 https://developers.weixin.qq.com/s/WcultVmb7Hmy 需求场景 自从有了iPhone底部小黑条之后,页面底部就有各种适配 小黑条还不止iPhone X这一种机型,后续新出的还要不要改代码? 可以通过js来匹配机型,可以通过媒体查询来匹配机型,新的机型如何适配? 解决办法 解决标准 希望尽可能少的改动,不需要js里面设置,然后模板里面再判断,然后再加个对应的样式啥的,太麻烦 希望尽可能通用,不能加了iPhoneX,又加iPhone XI,又加iPhone XII,没完没了 希望可以适配未来的类似的机型 解决思路 找到这个小黑条的尺寸获取方式, 在iPhone上可以通过如下方式获取(兼容写法)[代码] height:50px; height: calc(50px + constant(safe-area-inset-bottom)); /* ios < 11.2*/ height: calc(50px + env(safe-area-inset-bottom)); /* ios >= 11.2*/ [代码] 在我们页面样式对应的地方加上这个尺寸,需要就加上,不需要就不加 加的方式可以根据情况来选择 直接加在页面底部,padding 如果是吸底元素,要加元素的padding,通过加height高的方式也行 如果元素浮空,需要加margin的方式来设置,或者加底边距bottom的方式 当然内部加margin也行,需要注意背景颜色是否一致 有些地方需要全量的,有些地方可能需要高度折半,请自行选择 如果碰到一些特殊的情况,上面方式处理不了的,比如听说某些安卓机(我目前还没遇到),还可以回归原始的处理办法 媒体查询 配合JS通过getSystemInfo直接处理 [代码]screenHeight - safeArea.bottom[代码] 即是底部小黑条影响的范围,也就是上面方法求得的值 小程序中的解决办法 直接使用上面的兼容写法的适配方案即可 当前(20201128)最新的微信开发者工具开发版本上可以直接验证了,h5部分目前还不支持,开发哥哥么已经在搞了 H5中的解决办法 在html模板里面加如下meta标签,如果存在就合并一下, [代码] <meta name="viewport" content="viewport-fit=cover"> [代码] 然后用上面的兼容写法处理 手边没有设备怎么办? 模拟器 XCode(XCode 14) New =>iOS=>App类型的Application 接下来 Interface 选StoryBoard, Language选Swift 创建工程完成 把[代码]ViewController.swift[代码]代码改成如下:[代码]import UIKit import WebKit class ViewController: UIViewController { var webView: WKWebView! override func loadView() { webView = WKWebView() view = webView } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. let url = URL(string: "http://127.0.0.1:8080/iphone-style-adapt.html")! webView.load(URLRequest(url: url)) webView.allowsBackForwardNavigationGestures = true } } [代码] 在[代码]Info.plist[代码]中加入如下内容并合并<dict>标签 ,也就是把中间两行加入到dict标签中,(通过文本编辑器打开,或者XCode中以源码方式打开都行) [代码] <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> [代码]
2021-01-26 - 为什么图片链接可正常访问但image组件加载不出来图片?
因为 image 控件的图片拉取本质上是 web 上的 backgroundImage,很多时候是由于图片不规范(content-type / length / 是否302跳转等 )导致拉取不成功,最终表现为加载不出图片。关于这一块我们在持续优化中
2021-12-17 - 非常简单的长列表(无限上拉触底加载 onReachBottom)实现方案
我们知道小程序针对长列表有两个硬杠杠,一旦越界直接给白屏: 1、setData的数组数据不能超过1M。 2、DOM数不能太多,具体数据未知。 官方这样处理也不无道理,太长了本身性能确实也有问题。所以长列表一定要人为干预处理,不处理一直上拉加载肯定是不行的。 目前主流的处理方法有三种: 1、二维数组,就是把数据改为二维的,每一个分页数据作为一个一维数组的元素。这样处理,只解决了setData的问题,DOM的问题并未解决。并且把本来是一维的数据强行二维化,在很多逻辑处理上变得复杂。 2、官方提供了一个扩展组件recycle-view,但它要求item等高,存在局限性。https://developers.weixin.qq.com/miniprogram/dev/extended/component-plus/recycle-view.html 3、自行搭建骨架屏,类似于方案2的自研版本,根据自己的实际需要编写代码。实现成本非常高。 实现方案如下(太简单了,不提供代码示例): 1、思路:只保留最新的n页数据进行setData,每新加载一页数据,就舍弃最前面一页的数据。同时把第1页的数据保存起来,监听onPageScroll,如果发现用户拉回到了页面顶部,则舍弃所有数据,把第1页的数据setData回来。 2、举个例子:假设n=5,那么当加载了第6页数据时,第6页数据合并到数组尾部,把数组头部的第1页数据去掉,让setData的数据始终保持5页。这里有个细节要处理好,就是去除数据的时候先setData一次,新数据加载合并后,再setData一次,这样可以保证用户的scrollTop不会走位,停留在最新一条数据那个位置。 3、这个方案也存在一些弊端,看你实际项目中能否接受,主要有两个问题:a、用户如果倒着往回逐条浏览,体验是不连续的,因为中间一段我们已经舍弃掉了,如果拉到页面顶部时,将会出现直接回到第一条数据。b、去除数据的setData操作时,存在一定程度的闪屏现象。(针对问题a,应该可以解决,无非就是把数据再逐页塞回来,而不是像我的方案简单粗暴的回到第一页数据,如果项目有需要可以自行尝试。) 4、适用范围:比较适合信息处理类应用,比如后台管理系统。这类应用,往往头几屏内容就能找到信息,或者借助搜索,比较少会拉很多屏。而且往往处理完毕时是直接回到顶部的,不会逐条翻回去。所以这类应用只要保证不出白屏,一些小概率场景下存在一些几乎可以忽略的体验小瑕疵可以接受。信息浏览类应用,比如新闻应用,往往都是长列表浏览,小瑕疵就不一定能接受。
2020-10-28 - 如何实现input组件点击就全选内容,方便删除
如何实现input组件点击就全选内容,方便删除
2019-01-16 - input输入框获取焦点时全选文字?
如题,使用input输入框时能不能设置输入框获取焦点时全选输入框中的文字呢
2020-10-13 - input之全选
- 当前 Bug 的表现(可附上截图)[图片] 下次打开就不全选了 - 预期表现 全选的功能,只要设置就不出现bug - 复现路径 - 提供一个最简复现 Demo 为了更好的客户体检,我们功能需要input获取焦点的时候,能全选文本内容。 现在我通过focus='true' selection-start和selection-end来实现,编译后第一次能实现,后面再打开就不全选了。 不知道是不是微信的bug还是我用的不对,js里很简单就实现的功能,到这怎么那么难呢
2019-05-17 - 安卓系统input输入框输入值的时候跳转页面会清空输入内容或出现重叠现象,有劳尽快解决,谢谢
[图片] [视频]
2021-01-15 - input组件的bindfocus事件如何让其在键盘拉起之前触发?
input组件的bindfocus事件如何让其在键盘拉起之前触发? 在input的bindfocus时,弄了一个animation动画,可现在的情况是focus时,是先拉起键盘,再执行动画。 如何能让动画在键盘弹出之前或同时就开始执行?
2019-11-05 - Input组件在IOS上使用原生键盘选择展开选择文字时候失去焦点问题
已知问题,等待Input同层解决
2019-09-24 - 关于微信支付退款req_info字段解密问题
退款成功后退款通知回调req_info字段是加密的 现在通过文档进行base64解码 MD5加密之后进行 key*对加密串B做AES-256-ECB解密(PKCS7Padding)这一步的时候一直报 javax.crypto.BadPaddingException: pad block corrupted 这个错 百度了一堆方法尝试玩还是报这个错 有没有大佬有解决方案的 demo也只有PHP的 也是无语了
2019-03-19 - 退款结果通知解密req_info失败,麻烦看看代码有错误吗?
/** * 对微信的返回数据进行解密 做AES-256-ECB解密(PKCS7Padding) * @param encrypted 目标密文 * @param aesKey 解密密钥 * @param * @throws Exception */ public static String decryptWXReturn(String encrypted, String aesKey){ try { Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding","BC"); //这里是不是这样写? //对秘钥进行MD5编码 //这里生成key的方法是错的 Key key = initKeyForAES(MD5Util.encode(aesKey).toLowerCase().toString()); //这才是生成key的正确方法 SecretKeySpec key = new SecretKeySpec(MD5Utils.MD5Encode(aesKey,"UTF-8").toLowerCase().toLowerCase().getBytes(), "AES"); //对秘钥进行MD5加密的时候必须指定UTF-8编码,这样写也是不行的 SecretKeySpec key = new SecretKeySpec(MD5Util.encode(aesKey).toLowerCase().toLowerCase().getBytes(), "AES"); //这样也会报错 cipher.init(Cipher.DECRYPT_MODE, key); byte[] encryptedBase64 = new BASE64Decoder().decodeBuffer(encrypted); byte[] decbbdt = cipher.doFinal(encryptedBase64); //到这一步就开始报错pad block corrupted return new String(decbbdt,"UTF-8"); } catch (Exception e) { logger.error(e); } return null; } public static Key initKeyForAES(String key) throws NoSuchAlgorithmException { if (null == key || key.length() == 0) { throw new NullPointerException("key not is null"); } SecretKeySpec key2 = null; SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); random.setSeed(key.getBytes()); try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(256, random); //这里到底是128还是256??但是两种试了还是报错pad block corrupted //kgen.init(128, random); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); key2 = new SecretKeySpec(enCodeFormat, "AES"); } catch (NoSuchAlgorithmException ex) { throw new NoSuchAlgorithmException(); } return key2; } 秘钥是一致的,这个AES-256-ECB解密(PKCS7Padding)到底怎么解啊,请问代码有问题吗
2020-04-16 - 我的统一下单和普通直连分账接口用的同一个加密HMAC-SHA256 为什么统一下单可以通过而分账不可
这个坑跳不出来呀
2020-08-17 - 有什么方法可以获取小程序存储在本地文件的绝对路径?
有什么方法可以获取小程序存储在本地文件的绝对路径? 从手机存储的根目录开始
2019-08-30