页面滚动 鼠标移动上去暂停 移开滚动(亲测有用)

文章详细描述了一个Vue组件,用于创建可滚动的列表,支持鼠标悬停、离开和滚轮滚动事件。组件提供了滚动方向、速度控制以及滚动逻辑的定制选项。

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

 1、代码组件(vue 封装)


<template>
    <div class="custom-list" ref="scrollBody" @mouseenter="mouseenterFunc" @mouseleave="mouseleaveFunc" @mousewheel="mousewheelFunc">
        <div class="list-body" :class="{
            'list-body2': isHorizontal,
            canScroll:!isCanScroll
        }" ref="listBody" :style="{ transform: getScrollDistance() }">
            <slot></slot>
        </div>
        <div class="list-body" :class="{
            'list-body2': isHorizontal
        }" ref="tBody" v-if="isCanScroll" :style="{ transform: getScrollDistance() }">
            <slot></slot>
        </div>
    </div>
</template>
<script>
export default {
    props: {
        steep: {
            //滚动速度
            type: Number,
            default: 1,
        },
        scrollDirection: {
            //滚动方向
            type: String,
            default: 'top',
        },
        isRoller: {
            //是否可以滑轮滚动
            type: Boolean,
            default: true,
        },
        rollerScrollDistance: {
            //滑轮滚动的距离
            type: Number,
            default: 20,
        },

        isRoll: {
            //是否可以滑轮滚动
            type: Boolean,
            default: true,
        },
        data: Array,
    },
    computed: {
        isHorizontal() {
            return this.scrollDirection === 'left' || this.scrollDirection === 'right'
        },
    },
    data() {
        return {
            scrollDistance: 0, //滚动距离
            bodyHeight: 0, //滚动容器高度
            bodyWidth: 0, //滚动容器宽度
            listHeight: 0, //列表高度
            listWidth: 0, //列表宽度
            isStop: false,
            animationFrame: null,
            scrollBody: null,
            listBody: null,
            isCanScroll: true,
        }
    },
    mounted() {
        this.initData()
    },
    methods: {
        initData() {
            this.scrollDistance = 0
            this.isCanScroll = !0
            this.scrollBody = this.$refs.scrollBody
            this.bodyHeight = this.scrollBody?.clientHeight
            this.bodyWidth = this.scrollBody?.clientWidth

            this.listBody = this.$refs.listBody
            this.listHeight = this.listBody?.clientHeight
            this.listWidth = this.listBody?.clientWidth

            if ((this.bodyHeight !== 0 && this.listHeight !== 0 && this.listHeight >= this.bodyHeight) || (this.bodyWidth !== 0 && this.listWidth !== 0 && this.listWidth >= this.bodyWidth)) {
                this.isCanScroll = true
                this.start()
            } else {
                this.isCanScroll = false
            }
        },
        start() {
            return
            let isScrollFunc = (bodySize, listSize) => {
                if (bodySize > listSize || this.steep == 0) {
                    this.scrollDistance = 0
                    this.isCanScroll = !1
                }
            }
            this.isStop = !1
            //判断是否可以滚动
            if (!this.isHorizontal) {
                isScrollFunc(this.bodyHeight, this.listHeight)
            } else {
                isScrollFunc(this.bodyWidth, this.listWidth)
            }
            if (this.isCanScroll) {
                this.run()
            }
            //判断是否可以滚动函数
        },
        run() {
            //清空动画
            this.clearAnimation()

            this.animationFrame = window.requestAnimationFrame(() => {
                //滚动主逻辑函数
                let main = (listSize, bodySize) => {
                    let tempScrollDistance = Math.abs(this.scrollDistance)
                    if (this.scrollDistance < 0) {
                        let cc = 2 * listSize - bodySize
                        if (tempScrollDistance > cc) {
                            this.scrollDistance = -(listSize - bodySize)
                        }
                    } else {
                        this.scrollDistance = -listSize
                    }
                }

                //根据滚动方向判断使用高度或宽度控制效果
                if (!this.isHorizontal) {
                    main(this.listHeight, this.bodyHeight)
                } else {
                    main(this.listWidth, this.bodyWidth)
                }
                //判断滚动值
                if (!this.isStop) {
                    if (this.scrollDirection === 'top' || this.scrollDirection === 'left') {
                        this.scrollDistance -= this.steep
                    } else if (this.scrollDirection === 'bottom' || this.scrollDirection === 'right') {
                        this.scrollDistance += this.steep
                    }
                    this.run()
                }
            })
        },

        stop() {
            this.isStop = !0
            this.clearAnimation()
        },
        //获取滚动样式
        getScrollDistance() {
            let style
            if (!this.isHorizontal) {
                style = 'translate(0px, ' + this.scrollDistance + 'px)'
            } else {
                style = 'translate(' + this.scrollDistance + 'px,0px)'
            }
            return style
        },
        clearAnimation() {
            if (this.animationFrame) {
                cancelAnimationFrame(this.animationFrame)
                this.animationFrame = null
            }
        },

        mouseenterFunc() {
            this.stop()
        },
        mouseleaveFunc() {
            this.start()
        },
        mousewheelFunc(e) {
            if (!this.isCanScroll || !this.isRoller) {
                return false
            }
            let dis = e.deltaY
            if (dis > 0) {
                this.scrollDistance -= this.rollerScrollDistance
            } else {
                this.scrollDistance += this.rollerScrollDistance
            }
            this.run()
        },
    },
}
</script>

<style lang="scss">
.custom-list {
    white-space: nowrap;
    font-size: 14px;
    overflow: hidden;
    height: 100%;
}

.list-body {
    overflow: hidden;
    white-space: nowrap;
    font-size: 14px;
}

.canScroll {
    height: 100%;
    overflow: auto;
}

.list-body2 {
    display: inline-block;
}
</style>

2、代码引用

 <com-auto-scroll-mouse class="WH table-td" v-if="enterListTab.length" :data="enterListTab" :steep="0.5" scrollDirection="top" :isRoll="isRoll" :isRoller="true" :rollerScrollDistance="50">
                                <div class="width flex row-between padding5" id=" " :class="index % 2 == 0 ? 'sbgWe' : 'bgWeight'" style="color: black" v-for="(item, index) in enterListTab" :key="index">
                                    <div class="padding5 flex grad1">{{ index + 1 }}</div>
                                    <div>{{ item.enterName }}</div>
                                    <div @click="handleMap(item)"><img src="~@/assets/img/homeFirst/map.png" alt="" /></div>
                                </div>
                            </com-auto-scroll-mouse>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值