使用Movable-area實(shí)現(xiàn)小程序左滑刪除

在小程序中實(shí)現(xiàn)左滑刪除(側(cè)滑刪除)并不是一個(gè)很輕松的事情,因?yàn)橛袔讉€(gè)問(wèn)題(坑)是需要我們考慮的:

  1. 小程序的事件系統(tǒng)是存在缺陷的,其中不能在事件處理過(guò)程中調(diào)用preventDefault來(lái)動(dòng)態(tài)決定事件是否允許冒泡,假設(shè)用戶斜著滑動(dòng)一個(gè)條目時(shí),我們可能需要根據(jù)用戶滑動(dòng)的斜率等等來(lái)判斷這次滑動(dòng)是用來(lái)觸發(fā)側(cè)滑還是頁(yè)面滾動(dòng),在這方面的處理可能比較復(fù)雜。
    這里感謝 有專自媒體的踩坑文章: 微信小程序?qū)崿F(xiàn)左滑刪除-一切沒有那么簡(jiǎn)單
  1. 一般的,我們可能比較習(xí)慣這么去寫左滑刪除

左滑刪除代碼片段(優(yōu)化前)

html

<view wx:for='{{list}}' style="left:-{{item.offset}}rpx" class="scroll-view-item">
</view>

js

`touchMove`(e) {
      if (e.touches.length == 1) {
        let pointBefore = this.data.pointBefore;
        let thisPoint = e.touches[0];
        let slope = Math.abs(pointBefore.clientY - thisPoint.clientY) / Math.abs(pointBefore.clientX - thisPoint.clientX);
        console.log(slope)
        if (slope > 0.57) {
          return
        }
        let index = e.currentTarget.dataset.index;
        let offsetResult = 0;
        //手指移動(dòng)時(shí)水平方向位置
        let moveX = e.touches[0].clientX;
        //手指起始點(diǎn)位置與移動(dòng)期間的差值
        let disX = this.data.startX - moveX;
        let resultX = this.data.startOffset + disX;
        if (resultX <= 0) {//如果移動(dòng)距離小于等于0,說(shuō)明向右滑動(dòng),文本層位置不變
          offsetResult = resultX;
        } else if (resultX >= this.data.maxOffset) {
          //控制手指移動(dòng)距離最大值為刪除按鈕的寬度
          offsetResult = this.data.maxOffset;
        } else if (resultX > 0) {//移動(dòng)距離大于0,文本層left值等于手指移動(dòng)距離
          offsetResult = resultX;
        }
        //更新列表的狀態(tài)
        this.setData({
          offset: offsetResult
        });
      }
    }

但是在真機(jī)測(cè)試的時(shí)候總是卡卡的,一種可能是:

小程序不推薦在js里頭監(jiān)聽touchMove等ui事件并且每次都去修改ui內(nèi)容,原因:
WXS相應(yīng)事件

背景

有頻繁用戶交互的效果在小程序上表現(xiàn)是比較卡頓的,例如頁(yè)面有 2 個(gè)元素 A 和 B,用戶在 A 上做 touchmove 手勢(shì),要求 B 也跟隨移動(dòng),<movable-view> 就是一個(gè)典型的例子。一次 touchmove 事件的響應(yīng)過(guò)程為:

a、touchmove 事件從視圖層(Webview)拋到邏輯層(App Service)

b、邏輯層(App Service)處理 touchmove 事件,再通過(guò) setData 來(lái)改變 B 的位置

一次 touchmove 的響應(yīng)需要經(jīng)過(guò) 2 次的邏輯層和渲染層的通信以及一次渲染,通信的耗時(shí)比較大。此外 setData 渲染也會(huì)阻塞其它腳本執(zhí)行,導(dǎo)致了整個(gè)用戶交互的動(dòng)畫過(guò)程會(huì)有延遲。

另外,從CRP(標(biāo)準(zhǔn)渲染路徑)來(lái)說(shuō),我們這里頻繁地調(diào)用 setData來(lái)修改元素的 left 樣式,會(huì)導(dǎo)致網(wǎng)頁(yè)不斷地進(jìn)行 layout,style,composite操作,導(dǎo)致卡頓。而使用 transform 樣式僅影響composite操作,同樣可以做到元素的左移,這也是movable-view的做法。

使用movable-view的另一個(gè)好處

使用movable-view不需要我們手動(dòng)處理touchmove事件來(lái)修改左滑元素的位置,也因此避免了多次setData可能帶來(lái)的卡頓。

這里給出使用 movable-view 的代碼

左滑刪除代碼片段(優(yōu)化后)

js

Page({
  data: {
    x: wx.getSystemInfoSync().windowWidth / 750 * 200
  },
})

wxml

<movable-area style="height: 300rpx; margin-bottom: 24rpx;width:{{showLike?'700rpx':'900rpx'}};position:relative;left: {{showLike?'25rpx':'-175rpx'}};" >
    <movable-view
            x="{{x}}"
            class="scroll-view-item" style="width: 700rpx; height: 300rpx;"
            direction="horizontal" out-of-bounds="true">
        <view class="card-content" bind:tap="bindGroupTapInner">
            <text class="group-title">側(cè)滑刪除</text>
            </view>
        <view class="button-edit button-slide" bindtap="bindGroupEditTap">
            <i class="iconfont icon-editor"
               style='font-size:58rpx; color:white; position:absolute; top:14rpx; left:16rpx;'/>
        </view>
    </movable-view>
</movable-area>

稍微要注意一點(diǎn)的是控制好movable-view和movable-area的寬度和位置,這里由于不同的需求要求不同,建議手動(dòng)畫圖計(jì)算。

另外,movable-view內(nèi)部幫我們解決了事件傳遞的問(wèn)題,能夠左滑的touchmove就不會(huì)傳遞給外層的元素,估計(jì)是使用了wxs函數(shù)吧,好像wxs中處理事件是可以控制事件冒泡的,但是筆者還未嘗試,同時(shí)官方文檔有些不足,可以看這里。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 每天的學(xué)習(xí)記錄,可能有的地方寫的不對(duì),因?yàn)閯倢W(xué),以后發(fā)現(xiàn)錯(cuò)的話會(huì)回來(lái)改掉整體流程 https://develope...
    有點(diǎn)健忘閱讀 5,045評(píng)論 0 7
  • 配置文件 app.json的配置(全局) {// 用來(lái)配置頁(yè)面的路徑"pages":["pages/index/i...
    Q軒哥閱讀 27,377評(píng)論 2 31
  • 小程序 基本知識(shí) 項(xiàng)目文件 JSON 配置 小程序配置 app.json app.json 是對(duì)當(dāng)前小程序的全局配...
    勇敢的_心_閱讀 1,511評(píng)論 0 6
  • 因新工作主要負(fù)責(zé)微信小程序這一塊,最近的重心就移到這一塊,該博客是對(duì)微信小程序整體的整理歸納以及標(biāo)明一些細(xì)節(jié)點(diǎn),初...
    majun00閱讀 7,640評(píng)論 0 9
  • 閑逛虹許路,半罐啤酒蹲在草地上 兩個(gè)人開始瞎扯 憤怒的車子,呼嘯而過(guò) 不論我們討論的是姑娘還是天地 它都不曾停下來(lái)...
    逸云亦水閱讀 145評(píng)論 0 2

友情鏈接更多精彩內(nèi)容