小程序 movable-view 拖动排序

本文介绍了一种基于微信小程序的前端开发技术,通过Movable组件实现视频选择列表的拖动交互,并利用Intersection Observer观察器实时调整布局。开发者可以轻松理解并应用这种动态布局在实际项目中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

<movable-area class="movable" style="width:{{movableWidth}}px">
                <block wx:for="{{selectVideo}}" wx:key="coverImage" class="block">
                    <movable-view
                        class="movable__view {{item.coverImage === currentId?'zIndex':''}} {{item.coverImage === currentId && !movableDisabled ?'active':''}}"
                        data-id="{{item.coverImage}}" data-item="{{item}}" data-index="{{index}}" x="{{item.x}}"
                        y="{{item.y}}" disabled="{{movableDisabled}}" direction="all" catchlongpress="handleLongPress"
                        catchtouchend="handleTouchEnd" bindtouchmove="handleTouchMove">
                       
                        <image webp src="{{item.coverImage}}" class="image" mode="aspectFill"></image>
                    </movable-view>
                </block>
            </movable-area>

 


.movable .active {
    box-shadow: 0 6rpx 20rpx 0 rgba(0, 0, 0, 0.30);
}

.movable .zIndex {
    z-index: 1;
}

.movable {
    display: flex;
    width: 80%;
    height: 160rpx;
    margin: 0 30rpx;
    position: fixed;
    bottom: 80rpx;
}

.movable .movable__view {
    width: 156rpx;
    height: 156rpx;
    border-radius: 8rpx;
    overflow: hidden;
}

.movable .block {
    position: relative;
    height: 160rpx;
}

.movable .movable__view.active {
    box-shadow: 0 6rpx 20rpx 0 rgba(0, 0, 0, 0.30);
}

.movable .movable__view.zIndex {
    z-index: 1;
}

.movable .movable__view .image {
    width: 100%;
    height: 100%;
}

.movable .movable__view .close {
    position: absolute;
    top: 8rpx;
    right: 8rpx;
    width: 28rpx;
    height: 28rpx;
    z-index: 1;
}

function rpxToPx(rpx) {
    const { windowWidth } = wx.getSystemInfoSync();
    return rpx * (windowWidth / 750);
}
const RECT = {
    width: rpxToPx(160),
    height: rpxToPx(160),
    margin_right: rpxToPx(10),
    margin_top: rpxToPx(32),
};

Page({
    data: {
       
        selectVideo: [],// 拖动数据
        

        movableWidth: 0
    },
    onLoad: function (option) {
        this.generate(this.data.selectVideo);
    },
   
 
    generate(lists = []) {
        let that = this
        let renderLists = [], x = 0, y = 0;
        for (let i = 0; i < lists.length; i++) {
            x = (RECT.width + RECT.margin_right) * i;
            y = RECT.margin_top;
            const item = {
                ...lists[i],
                x,
                y,
            };

            renderLists.push(item);
        }
       
        console.log(renderLists)
        that.setData({
            selectVideo: renderLists,
           
            movableWidth: renderLists.length * (RECT.width + RECT.margin_right),
        });
    },
    refreshLists(insertIndex) {
        let { selectVideo } = this.data;
        const origin = selectVideo.find(item => item.coverImage === this.data.currentId);
        if (!origin) {
            return
        }
        selectVideo.splice(this.originIndex, 1);
        selectVideo.splice(insertIndex, 0, origin);
        this.generate(selectVideo);
    },
    createMovableObserver() {
        this.movableObserver && this.movableObserver.disconnect();
        this.movableObserver = this.createIntersectionObserver({
            thresholds: [0.3],
            observeAll: true,
        });
        this.movableObserver
            .relativeTo('.movable__view.active')
            .observe('.movable__view', (res) => {
                const {
                    intersectionRatio,
                    dataset,
                } = res;
                if (intersectionRatio < 0.3 || intersectionRatio === 1) return;
                this.refreshLists(dataset.index);
                this.movableObserver && this.movableObserver.disconnect();
            });
    },
    handleLongPress(e) {
        console.log(e.currentTarget.dataset.id)
        const { id, index } = e.currentTarget.dataset;
        this.originIndex = index;
        this.setData({
            movableDisabled: false,
            currentId: id,
        }, () => {
            this.createMovableObserver();
        });
    },
    handleTouchEnd() {
        if (this.data.movableDisabled) return;
        this.setData({
            movableDisabled: true,
            selectVideo: this.data.selectVideo
        });
    },
    handleTouchMove() { },
})

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值