微信小程序的小问题
无法实现动态字体引入
这个属于小程序设计问题,因为无法动态创建 css,所以也就无法引入动态生成的 css。一种解决办法是使用后端生成图片,然后页面引入图片。例如使用 node-canvas 模块,比较麻烦就是要在服务器上配置好字体。
小程序后续可能会引入载入自定义字体方案来解决这个问题。
canvas 设置不了 height 和 width 属性
也是一个恶心的设计问题,小程序这里没有没有遵循 web 规范。Canvas 的宽高不应该等同于 css 设置的宽高,而是应该可以独立设置。这种设计导致了我们无法针对高分屏生成高精度的 canvas 或者生成可缩放的高分辨率图片。
已向官方提出需求,希望他们能改进。
textarea 设置不了 lineheight 和 padding 样式
textarea 在移动端使用原生组件实现,在 IOS 上设置 lineheight 和 padding 无效,这导致 textarea 总会在左上有一个 padding,这对于某些视觉强迫症来说很难接受。一个办法是使用 input 假装成 textarea,或者在外层使用 css 的 transform 强制对齐,但是这样灵活性太差,强烈不推荐。另一个是层级问题 它会一直保持最高级。
movable-view 使用 css 的 scale 进行缩放
这种实现方式会导致一个问题:你无法使用 movable-view 模拟图片预览,来查看提高显示的精度,因为就算你里面的图片是高清的,scale 放大后还会是模糊的。一种办法是自己实现双指缩放,通过改变元素宽高而不是 scale 来放大图片,另一种办法是在后端合成出一个图片,然后使用 previewImage 这个 API 进行预览。
希望官方可以增加一种改变宽高的缩放方式。
audioContext 对象第一次触发 onPlay 回调时 duration 属性无法获取
小程序 bug,开发者工具可重现。更坑的是它不是返回 null,而是 0。
一个解决办法是在 onTimeUpdate 回调里获取 audioContext 的 duration,这里的 duration 总是存在。
audioContent canPlay 回调后音频还是无法正常开始播放
canPlay 回调完 IOS 上音频还是无法正常开始播放, 下载仍然继续。可以在 play 调用后加了一个 setTimeout 判定 500 毫秒后如果播放还没触发,则提示用户等待加载。
recorderManager 对象调用 resume 方法后开发工具不会回调 onStart,而 IOS 上会
小程序 bug,但是说不清楚是 IOS 实现的问题,还是开发者工具的问题,解决办法就是判定一下:
let started = false recorderManager.onStart(() => { if (started) return started = true // do something on start })
动态改变 css 的 animation-play-state 属性 IOS 不起作用
css 的 animation-play-state 属性可以设置为 running 和 paused 来开启和暂停 css 动画,但是不知为何在小程序的 IOS 设备上无效,无论是通过 css 还是 style 属性设置都无效。解决办法是 javascript setInterval 动态计算属性,然后 setData。
已向官方反馈该问题。
backgroundAudioManager.title 必填
不知是 bug 还是他们文档没写好,如果不填 title 在 IOS 会报 title is nil 这个错误,但是开发者工具可以正常播放。
这个问题很容易发现,记得填上就是了。
canvas 的 draw 函数部分机型不触发 callback 回调
首先小程序文档就没写清楚 callback 怎么调用,正确的调用方法是这样的:
ctx.draw(true, () => { // export image })
如果你不想导出一团黑就需要在 draw 的 callback 里面做图片导出操作。
我们发现在安装了最新版微信 6.6.6 的 iPhone X 上面这个回调不会触发。 鉴于这个问题不好处理,我们后面使用后端来处理图片导出了,后端的另一个好处就是改完不用等小程序审核。
app 进入后台会缓存数据传递
一个算不上 bug 的 bug。如果你在 setInterval 函数里面调用 setData 会在 IOS 上发现 setData 调用会在小程序进入后台再进入后多次连续调用,换句话说,setData 的调用在小程序进入后台后被缓存了起来,然后当小程序回到前台又会被依次重新触发。如果你不想要这种情况可以在 app.js 保存当前应用可见状态:
onShow() { this.globalData.appShown = true }, onHide() { this.globalData.appShown = false }
然后在回调里面判定下就可以了。