动态

详情 返回 返回

uniapp微信小程序長按功能 - 动态 详情

現在要實現一個按鈕長按的功能,大概有如下幾個要點:
1、長按按鈕,按鈕覆蓋整個輸入框
2、長按的過程中移動手指,判斷手指移動的位置是否在按鈕內
3、長按鬆開,按鈕還原

按鈕結構如下:

<view 
  id="audio-full" 
  :class="[
    'audio-full', 
    isLongpress && 'touch-longpress'
    ]" 
    v-if="isAudio" 
    @longtap="onLongtap" 
    @touchmove="onTouchmove" 
    @touchend="onTouchend">
        {{isLongpress ? '長按':'未長按'}}-位置 {{isOutOfBounds ? '外' : '內'}}
</view>

長按主要用到以下核心功能:
● @longtap
● @touchmove
● @touchend

具體描述官網有寫:https://uniapp.dcloud.net.cn/component/canvas.html#canvas

下面拆解一下如何實現:
當我們長按的時候,會觸發@longtap事件,我們在該事件內獲取到按鈕的dom元素信息

import { getCurrentInstance,nextTick } from 'vue';
const { proxy } = getCurrentInstance();
const query = uni.createSelectorQuery().in(proxy);

let buttonRect = null; // dom元素
const isLongpress = ref(false); // 是否長按
const onLongtap = () => {
    isLongpress.value = true;
  // 在nextTick內獲取dom信息,此時可以拿到正確的dom大小
    nextTick(() => {
        query
            .select('#audio-full')
            .boundingClientRect((data) => {
                buttonRect = data;
                console.log('dom信息' + JSON.stringify(buttonRect));
            })
            .exec();
    });
};

通過uni.createSelectorQuery + query.select('#domId').boundingClientRect查詢節點信息
文檔:https://uniapp.dcloud.net.cn/api/ui/nodes-info.html#createsel...


拿到dom信息後,用户可能會移動手指,比如語音上滑取消錄音功能,此時我們要判斷手指移動是否處在按鈕範圍內,移動手指會觸發@touchmove事件

const isOutOfBounds = ref(false); // 是否超出邊界
const onTouchmove = (e) => {
    if (!buttonRect) return
    const touch = e.touches[0];
    const { left, top, width, height } = buttonRect;
    // 判斷觸摸點是否超出按鈕範圍
    isOutOfBounds.value = touch.clientX < left || touch.clientX > left + width || touch.clientY < top || touch.clientY > top + height;
};

最後鬆開,還原按鈕

const onTouchend = () => {
    isLongpress.value = false;
};

完整核心代碼如下:

<view 
  id="audio-full" 
  :class="[
    'audio-full', 
    isLongpress && 'touch-longpress'
    ]" 
    v-if="isAudio" 
    @longtap="onLongtap" 
    @touchmove="onTouchmove" 
    @touchend="onTouchend">
        {{isLongpress ? '長按':'未長按'}}-位置 {{isOutOfBounds ? '外' : '內'}}
</view>
let buttonRect = null; // dom信息
const isOutOfBounds = ref(false); // 是否超出按鈕邊界

// 長按觸發
const onLongtap = () => {
    isLongpress.value = true;
    nextTick(() => {
        query
            .select('#audio-full')
            .boundingClientRect((data) => {
                buttonRect = data;
                console.log('dom信息' + JSON.stringify(buttonRect));
            })
            .exec();
    });
};

// 移動觸發
const onTouchmove = (e) => {
    if (!buttonRect) return
    const touch = e.touches[0];
    const { left, top, width, height } = buttonRect;
    // 判斷觸摸點是否超出按鈕範圍
    isOutOfBounds.value = touch.clientX < left || touch.clientX > left + width || touch.clientY < top || touch.clientY > top + height;
};

// 觸摸鬆開
const onTouchend = () => {
    isLongpress.value = false;
};

參考文檔:
uniapp按鈕長按和觸摸事件
查詢節點信息的對象

Add a new 评论

Some HTML is okay.