在作一個小球跟隨手指移動的效果時候,因爲在touchmove事件中頻繁調用setData改變小球的位移實現,在開發工具和IOS平臺還算流暢,但在安卓機下手機預覽出現極其卡頓的交互,簡直是不堪入目。html
可微信web開發者工具打開 片斷代碼https://developers.weixin.qq.com/s/B9UHyvmo7t6tweb
setData每秒調用高達50左右形成的。 引用官方的話就是:小程序
a、touchmove 事件從視圖層(Webview)拋到邏輯層(App Service)bash
b、邏輯層(App Service)處理 touchmove 事件,再經過 setData 來改變 組件 的位置微信
一次 touchmove 的響應須要通過 2 次的邏輯層和渲染層的通訊以及一次渲染,通訊的耗時比較大。此外 setData 渲染也會阻塞其它腳本執行,致使了整個用戶交互的動畫過程會有延遲。app
movable-view + movable-area可實現移動效果很流暢,可是也有侷限性不能知足複雜的需求,例如如今需求須要是兩個小球使用兩個手指能同時控制小球移動,則沒法實現,還須要配合setData來實現,使用了setData必然會出現卡頓dom
從基礎庫 2.4.4 開始支持 WXS響應事件 直接上代碼,本人菜鳥,代碼寫的很亂:ide
index.js函數
const app = getApp()
Page({
data: {
balls: [1, 2, 3, 4, 5, 5, 6, 7]
}
})
複製代碼
index.wxml工具
//引入wxs文件
<wxs module="index" src="./index.wxs"></wxs>
<view class='wrap' catchtouchstart='{{index.touchstart}}' catchtouchmove='{{index.touchmove}}' catchtouchend='{{index.touchend}}'>
<view class="demo hide" wx:for="{{ balls }}"></view>
</view>
複製代碼
index.wxs
var allTouchs = [], len = 0, instances = [], instanceLen, isMoveEnd = false
function reset(ownerInstance) {
//重置
for (var i = 0; i < instanceLen; i++) {
instances[i].setStyle({
'transform': '',
'display': 'none'
})
}
}
function touchstart(event, ownerInstance) {
if (isMoveEnd) return
//獲取當前移動的手指
var bounds = event.touches, boundsLen = bounds.length
allTouchs = event.touches, len = event.touches.length
instances = ownerInstance.selectAllComponents('.demo'), instanceLen = instances.length
for (var i = 0; i < instanceLen; i++) {
var instance = instances[i], bound = bounds[i]
if (i < boundsLen) {
//更新
instance.disabled = false
instance.identifier = bound.identifier
instance.setStyle({
'transform': 'translateX(' + bound.pageX + 'px) translateY(' + bound.pageY + 'px)',
'display': 'block'
})
} else {
instance.setStyle({
'transform': '',
'display': 'none'
})
instance.disabled = true
instance.identifier = ''
}
}
}
function touchmove(event, ownerInstance) {
//獲取當前移動的手指
var bounds = event.changedTouches, boundsLen = bounds.length, bound = null, instance = null, allTouch = null
for (var i = 0; i < instanceLen; i++) {
instance = instances[i]
for (var j = 0; j < boundsLen; j++) {
bound = bounds[j]
if (instance.identifier === bound.identifier) {
//更新
instance.setStyle({
'transform': 'translateX(' + bound.pageX + 'px) translateY(' + bound.pageY + 'px)',
'display': 'block'
})
}
}
}
}
function touchend(event, ownerInstance) {
isMoveEnd = true
//獲取當前移動的手指
var bounds = event.changedTouches, boundsLen = bounds.length, bound = null, instance = null, allTouch = null
for (var i = 0; i < instanceLen; i++) {
instance = instances[i]
for (var j = 0; j < boundsLen; j++) {
bound = bounds[j]
if (instance.identifier === bound.identifier) {
//更新
instance.setStyle({
'transform': '',
'display': 'none'
})
//移除
instances[i].disabled = true
instances[i].identifier = ''
}
}
}
var tmp = instances.filter(function (item) {
return !item.disabled
})
if (tmp.length < 1) {
//重置
reset(ownerInstance)
}
isMoveEnd = false
}
module.exports = {
touchmove: touchmove,
touchend: touchend,
touchstart: touchstart
}
複製代碼
微信web開發者工具打開小程序代碼片斷https://developers.weixin.qq.com/s/wLxQuwm1786m
instance對象支持的方法:
通過實機測試,不出出現卡頓效果
官方bug:
我的總結bug:
1.wxs不能使用ES6+語法,不然會報錯(勾選了ES6轉ES5也沒用)
2.console.log()
不能直接打印對象,須要JSON.stringify
3.固然不能調用app service
環境中的方法和wx.xxxx方法