uniapp实现小程序拖拽购物车,类似苹果的 Assistive Touch且限制拖拽位置不能脱出页面安全区;

  • Post author:
  • Post category:uniapp



如果是单页面使用不用父组件传过来,我是需要多页面公用购物车位置所以需要传进来;

// 防抖
export function _debounce(fn, delay) {

    var delay = delay || 2000;
    var timer;
    return function() {
        var th = this;
        var args = arguments;
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(function() {
            timer = null;
            fn.apply(th, args);
        }, delay);
    };
}
<template>
    <movable-area class="fixed-box" :style="'height:'+height+'px;'">
        <movable-view id="movable_view" class="fixed-button" :x="x" :y="y" :friction="40"  direction="all"  @change="onChange"
            :inertia="false" :damping="200" @click="openUrl">
            <text class="cart-num">{{cartNum>0?cartNum:''}}</text>
        </movable-view>
    </movable-area>
</template>

<script>
    import {
        _debounce
    } from '@/utils/util.js'
    export default {
        props: {
            fatherX: {
                type: Number,
                default: uni
                    .getSystemInfoSync().screenWidth
            },
            fatherY: {
                type: Number,
                default: -120
            },
            cartNum: {
                type: Number,
                default: 0
            }
        },
        data() {
            return {
                height: 500,
                sysyInfo: uni.getSystemInfoSync(),
                x: 1000,
                y: -120,
                old: {
                    x: 0,
                    y: 0
                },
                isIos: uni.getSystemInfoSync().model.indexOf("iPhone") > -1,
            }
        },
        computed: {
            halfScreenMove() {
                return (this.sysyInfo.screenWidth - 24) / 2
            }
        },
        created() {
            this.$nextTick(() => {
                let height = 500;
                this.x = this.fatherX;
                this.y = this.fatherY;
                height = this.sysyInfo.safeArea.height - (this.isIos ? 44 : 48)
                this.height = height
            })
        },
        mounted() {
            setTimeout(() => {
                console.log(this.x, this.y, this.sysyInfo)
            }, 3000)
        },
        methods: {
            openUrl() {
                uni.navigateTo({
                    url: '/pages/integral/buycar'
                })
            },
            tap() {
                this.x = this.old.x
                this.y = this.old.y
                this.$nextTick(function() {
                    const query = uni.createSelectorQuery().in(this);
                    query.select('#movable_view').boundingClientRect(({
                        left
                    }) => {
                        if (left <= this.halfScreenMove) {
                            this.x = -10
                        } else {
                            this.x = this.halfScreenMove * 4
                        }
                        setTimeout(() => {
                            uni.setStorageSync('x', this.x)
                            uni.setStorageSync('y', this.y)
                        })
                    }).exec();

                })
            },
            recordMove: _debounce(function(e) {
                this.tap()
            }, 300),
            onChange(e) {
                this.old.x = e.detail.x
                this.old.y = e.detail.y
                this.recordMove()
            }
        }
    }
</script>

<style scoped>
    .fixed-box {
        pointer-events: none;
        width: 702rpx;
        position: fixed;
        left: 24rpx;
        bottom: 0;
        z-index: 100000;
        /* background: #000; */
    }

    .fixed-button {
        pointer-events: auto;
        width: 100rpx;
        height: 100rpx;
        background-image: url(icon_buycar2.png);
        background-size: cover;
        overflow: hidden;
        z-index: 9999;
        display: flex;
        align-items: center;
        justify-content: center;
        left: 20rpx;
        top: 85vh;
    }

    .cart-num {
        border-radius: 50%;
        position: relative;
        top: -30rpx;
        right: -18rpx;
        color: red;
        font-size: 26rpx;
        font-weight: bold;
        text-align: center;
    }

    @supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
        .fixed-box {
            bottom: constant(safe-area-inset-bottom);
            bottom: env(safe-area-inset-bottom);
        }
    }
</style>



版权声明:本文为webhejian原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。