小程序踩坑记

47次阅读

共计 3680 个字符,预计需要花费 10 分钟才能阅读完成。

小程序踩坑记
希望这个文章 能尽量记录下小程序的那些坑,避免开发者们浪费自己的生命来定位到底是自己代码导致的还是啥神秘的字节跳变原因。

前记
小程序大多数坑是同一套代码在不同平台上表现不一致导致的,微信开发者工具,Android,iOS。千万不要以为自己写的代码在模拟器上跑过了就完事了,一定需要在 Android 和 iOS 真机上再测一遍,否则后果不堪设想。之所以有如此坑爹的情况,也是由于小程序在不同系统下使用的底层框架不一致导致的,如下图所示。

另:小程序的视图层和 js 代码运行在不同的地方,相当于小程序的视图层运行在浏览器中,而 js 运行在原生的 js 解析引擎上。这也是为啥小程序的 js 无法获得 dom 和 bom 的原因。

坑们
1,onShareAppMessage 中设置封面在 Android 和 iOS 上展示策略不一致
相关文档

https://developers.weixin.qq….

现象

当设置的 imageUrl 不是 5:4 的图片时,比如 5:3 时,就会出现下列情况,左边是在 Android 上的展示,右边是 iOS 上的。两者对分享消息的封面展示策略并不一样。

版本

明显 iOS 上更合理一点,目前 Android 微信版本 6.6.7 依然会发生这种情况。

解决

像这种非 5:4 的图片,尽量也弄成 5:4 的,然后多余部分用白色进行填充。

2,wx.showToast 在 iOS 和 Android 上行为不一致
相关文档

https://developers.weixin.qq….

现象

当 showToast 后,马上返回上一个页面,在 Android 上,toast 依然存在,但 iOS 上 toast 无法显示。感觉是因为在 Android 上这个 toast 是全局的,而 iOS 上 toast 只是依附于某个页面。

解决

如果想在这种情况下,Android 和 iOS 都能显示出 toast,那只能加个 timeout 延时了,比如 1s 后再 执行 wx.navigateBack(); 的操作。

3,小程序的 web-view 中页面跳转后,点击 Android 手机上的物理返回按钮会返回前一个页面。而点击左上角的返回按钮,会直接关闭整个 web-view。
4,原生组件之坑
小程序可能为了实现方便,其中几个组件使用了原生组件,canvas,textarea,map,camera,video,live-player,live-pusher。而原生组件的层级最高,无法通过 z-index 来控制。而且也无法在 scroll-view、swiper、picker-view、movable-view 中使用这几个原生组件,否则效果可谓是惨不忍睹。

解决

使用 cover-view 和 cover-image 来覆盖在原生组件之上

相关文档:https://developers.weixin.qq….

5,video 组件的视频源地址不能有中文,否则在 iOS 上无法加载
相关文档

https://developers.weixin.qq….

现象

视频源地址设置中文后,Android 和模拟器上是可以正常播放的,但 iOS 上无法播放。

6,wx.showToast 文字最多可显示两行,多出部分会被截断,所以注意控制自己提示的内容。
7,wx.showModal 的 title 在 iOS 上只能显示一行,而在 Android 上可以显示两行。多出会 …。
8,wx.showActionSheet 在 Android 和 iOS 上面行为差异过大。
https://developers.weixin.qq….

iOS 会从下部滑动上来,Android 会弹一个中间列表弹框。而且 iOS 的列表中会多一个”取消“的选项,更坑爹的时,后来一个版本竟然把 Android 的点击外部取消功能给干掉了,导致 Android 上只能按返回键才能取消 ActionSheet。

我也不知道腾讯写的这个注意文档到底是为了啥。

注意
Android 6.7.2 以下版本,点击取消或蒙层时,回调 fail, errMsg 为 “fail cancel”;
Android 6.7.2 及以上版本 和 iOS 点击蒙层不会关闭模态弹窗,所以尽量避免使用「取消」分支中实现业务逻辑
9,在 iOS 上两个 Image 重合摆放,但更高层级上的 Image 无法显示问题
微信小程序图片在同一父标签下重叠排布的时候会产生问题,具体表现为无论如何设定 z -index,悬浮在上的图片一直会被沉在下方的图片遮盖。这个问题仅仅反映在 iOS 10.3.3 机型上,在模拟器和 Android 上都没有问题。

在真机调试中发现,是小程序 image 标签,自带的 overflow:hidden;产生了影响,在取消该属性后就正常显示了。

1,替换为 overflow:visble;等方式未起作用。解决办法有两种:

2,使用 cover-image 代替上浮图片的 image 标签,这样在 ios 和 android 上都显示正常,但是在模拟器上似乎有些问题。

3,使用一个 view 包裹上浮的图片。这样在三端表现一致且能解决上述问题。

10,有关 web-view 中有背景音乐,后台后无法关闭的问题
https://developers.weixin.qq….

var hiddenProperty = ‘hidden’ in document ? ‘hidden’ :

'webkitHidden' in document ? 'webkitHidden' :
'mozHidden' in document ? 'mozHidden' :
 null;


if (hiddenProperty) {

var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange');

var onVisibilityChange = function() {if (document[hiddenProperty]) {!MpMovie.video.paused && MpMovie.video.pause();

}

};

document.addEventListener(visibilityChangeEvent, onVisibilityChange);
11,web-view 中调用如 openLocation 需要鉴权问题
https://mp.weixin.qq.com/wiki… 此处鉴权必须得使用一个公众号的 appId 和 appsecret 才行。

不能用对应小程序的

千万不能用对应小程序的

12,wx.showActionSheet 在 Android 和 iOS 上面行为差异过大。
Canvas 篇
因 Canvas 坑实在太多,把 Canvas 的坑单独列出来

1,wx.canvasToTempFilePath 在模拟器和真机上行为不一致
相关文档

https://developers.weixin.qq….

现象

使用 Canvas 绘图成功后,直接调用该方法生成图片,在 IDE 上没有问题,但在真机上会出现生成的图片不完整的情况。

解决

需要加个神秘的 timeout(300ms,再少就不行了)时间后,再调用该方法,这样生成的图片才完整。下面是社区里面的一篇帖子。

https://developers.weixin.qq….

2,canvasContext.font 的几个坑
相关文档

https://developers.weixin.qq….

size 不能使用小数
如果设置 font 中字体大小部分包含小数,则会导致整个 font 设置无效。

style 设置 italic 问题
如果设置为 italic,在 Android 机上只有同时设置 weight 为 bold 才能生效。在 iOS 上,不管设不设置都不生效。而真机上是正常的。

3,canvasContext.drawImage 的坑
相关文档

https://developers.weixin.qq….

在 IDE 中可以直接设置网络图片进行绘制,但在真机上设置网络图片无用
解决

使用 painter 库进行绘制,https://github.com/Kujiale-Mo…。Painter 在进行图片绘制前,会先进行图片下载操作,并且还会把下载的图片存储本地,进行 LRU 管理,让后续绘制同样图片时,节省下载时间。

在 IDE 中可设置 base64 的图片数据进行绘制,但真机上无用
解决

先把 base64 转成 Uint8ClampedArray 格式。然后再通过 wx.canvasPutImageData(OBJECT, this) 绘制到画布上,然后把画布导出为图片。

4,canvasContext.clip 的一些坑
相关文档

https://developers.weixin.qq….

canvasContext.clip 方法在 iOS 设备上的微信 6.6.6 版本及以下会导致该 clip 下面使用的的 restore 方法失效。
在 clip 之前如果设置了,setFillStyle 为透明,在 Android 上会直接导致所裁图片无法显示。而 IDE 和 iOS 上无此问题。
解决

如果想实现圆角,还是使用 Painter 库来解决。https://github.com/Kujiale-Mo…。

正文完
 0

小程序采坑记

48次阅读

共计 2538 个字符,预计需要花费 7 分钟才能阅读完成。

小程序采坑记

上手小程序两个月,多多少少遇到一些坑,在此简单地作下总结。希望能对那些跟我一样有遇到过同样问题的人提供一点帮助,避免掉进这些坑,少走一些弯路。因为自己比较菜,也讲不了多少有用的东西,欢迎大神指教~~

1. swiper 组件高度的自适应问题

用过小程序 swiper 组件的 everybody 应该都知道,在 swiper 组件里只可放置 swiper-item 组件,否则会导致未定义的行为。但一些人可能会遇过这种情况:已知小程序 swiper 组件默认高度 150px,如果子元素高度过高,swiper不会自适应高度。

这种情况挺坑的。。要动态的改变 swiper 的高度,还得靠 wx.createSelectorQuery()(在自定义组件或包含自定义组件的页面中,应使用 this.createSelectorQuery() 来代替)创建一个SelectorQuery 对象实例,通过选择器获取组件的高度去动态地改变swiper 的高度,麻烦。

2. scroll-view 组件内嵌原生组件

scroll-view组件不得不说,挺坑的,尤其是在与原生组件配合着使用的时候,容易出现”惊喜“的效果。在 scroll-view 里内嵌 textarea 原生组件,真机调试上 textarea 直接不跟着滑动;在 scroll-view 里内嵌 input 组件,安卓手机的测试正常,iPhone上却出现了 input 框里输入数字重叠的情况 …… 流泪 ing…

有个解决的方法是,用 view 组件替代 scroll-view 组件,在 view 组件里设置属性 scroll-yscroll-x,可模拟 scroll-view 的滑动功能,但需要给 view 组件设置 {overflow: auto;} 的样式才行。

3. 公共属性 hidden 失效的问题

有些人可能一直使用 hidden 都没出什么问题,觉得 hidden 是一直生效的,但实际上 hidden 属性也有失效的时候。

举个栗子,用最简单的代码阐述这个现象:

<view hidden> 啦啦啦 </view>
<view style="display: block" hidden> 啦啦啦 </view>

你会发现,前一个被成功隐藏了,但是后一个不会被隐藏。

一句话:在 style 属性里设置 display 属性会直接让 hidden 属性失效

4. switch 组件

先引用下官方文档的说明:

可发现,这里仅有一个 color 样式可设置,若要改变 switch 组件的尺寸,还得这样写:

.wx-switch-input{
    width: 82rpx!important;
    height: 40rpx!important;
}
.wx-switch-input::before{
    width: 80rpx!important;
    height: 36rpx!important;
}
.wx-switch-input::after{
    width: 38rpx!important;
    height: 36rpx!important;
}

这种处理方式,虽然起作用了,但实际上可以看出,尺寸的设置依旧有很大的限制(可以自己试试),并不推荐这种做法。比较好的方法是引入第三方的组件库,例如直接用 Vant Weapp 里的 switch 组件。

5. 原生组件 input 无法被 cover-view 和 cover-image 之外的组件覆盖?

对于这个问题,可能很多人都会回答说:是的。但实际上真是这样吗?

其实小程序的 input 组件表现挺奇怪的。首先,官方文档说他仅在 focus 时表现为原生组件。

这句话直到现在,我也觉得挺有问题的。来看看这个栗子吧,看看 input 组件的神奇表现:

<view style="position: relative">
      <image 
         src='/pages/image/location.png'
         style="position: absolute; top: 10rpx; z-index: 1; width: 100rpx; height: 100rpx; background: gray"
         bindtap="click" >
      </image>
      <input
         style="background: yellow; border: 1px solid #000; height: 120rpx; width: 100vw;"
         bindinput="inputHandler"
         placeholder="请输入你的文字~~~"
         placeholder-style="color:#999" />
</view>

效果如下:

这是 input 框未输入文字(不管有没有聚焦)时的表现。如果此时输入文字,就会变成酱紫:

神奇不神奇?好吧,就算你说不神奇,我也要继续。这里特地给 input 组件添加了背景色,可看出,当输入了文字时,图片却并没有能覆盖 input 组件,图片上绑定的 click 方法是触发不了的。但 input 组件的背景色此时竟无法覆盖图片的样式。

此刻你可能会问:就这样?还有没有别的?

嗯嗯 ……. 问得好!当然还有另外的现象。

细心的你可能注意到了,上面的代码中,image组件的层级设为了 1。这个如果设置得大一点,有没有影响呢?

你可能会说:input那可是原生组件啊,image的层级再大,一样的,没区别。

真是这样吗?现在直接把 imagez-index的值设为 2,为了避免挡住视线,决定把 image 组件移至右边,故设置了样式{right: 20rpx}。结果如下:

…… 好了,意外又出现了,你可以去买彩票了 ……

设置 image 组件层级为 1 时,若 input 框未输入文字(不管有没有聚焦),此时是会覆盖 image 组件的样式的,但是 image 层级为 2 时已经覆盖不了了。但是在输入了文字时的表现上,和尝试着点击 image 组件上的 click 方法时的表现上,还是一样的。

image 组件的层级设置为 3 呢?奇迹开始了。因为此时点击 image 组件成功地触发 click 方法。换句话说就是:原生组件 input 已经被 cover-view 和 cover-image 之外的组件覆盖了

原文链接 欢迎来撩鸭!!!

]

【作者简介】黄彦森,芦苇科技 web 前端开发工程师,喜欢唱歌、看动漫、看小说。擅长微信小程序开发,系统管理后台。访问 www.talkmnoney.cn 了解更多。

正文完
 0