通过 js 解决滑动浮动按钮时候页面被跟着滚动的尴尬问题

这个问题好几个项目到遇到,一直没得到很好(完美)的解决,可能之前的项目比较赶,一直没时间去研究,后面到了一家相对比较自由的公司,终于有时间研究这些疑难杂症了,然后就想到了一个办法:

1.对于浮动的按钮,或者页面上可以滑动的元素,可以这么做,当touchStart事件被触发的时候,就执行以下代码:

document.body.style.overflow = 'hidden'

当touchend事件被触发的时候,就执行以下代码:

document.body.style.overflow = 'auto'

然后就发现拖动按钮或者元素底层的页面就不会滑动了

2.对于弹窗,原理也相同,出现弹窗的时候执行:

document.body.style.overflow = 'hidden'

关闭弹窗的时候执行:

document.body.style.overflow = 'auto'

若您还不清楚,我写个完整的vue项目demo组件,是对于以上第一点,在页面上滑动浮动按钮的,然后您在页面中直接引入这个组件即可查看到效果:
通过 js 解决滑动浮动按钮时候页面被跟着滚动的尴尬问题_第1张图片

<style lang="scss">
.float_info{
	box-shadow: 0px 1px 1px 1px rgba(0, 0, 0, 0.1);
	color: #666666;
	transition: all 0.3s;
	position: fixed;
	bottom: 436px;
	right: 6px;
	width: 80px;
	height: 80px;
	display: flex;
	flex-flow: column;
	justify-content: center;
	align-items: center;
	z-index: 999;
	// background: rgba(0, 0, 0, 0.5);
	border-radius: 35px;
	cursor: pointer;
	// user-select: none;
	.text{
		font-size: 24px;
		color: #fff;
	}
	img{
		width: 44px;
		height: 44px;
	}
}
</style>
<template>
    <div
        ref="floatButton"
        class="float_info"
        :style="{'width': itemWidth + 'px', 'height': itemHeight + 'px', 'left': left + 'px', 'top': top + 'px'}"
		@touchstart="touchStart"
		@touchmove="touchmove"
		@touchend="touchend"
		@click="onBtnClicked"
    >
    	<img src="../assets/img/fifteenCul.png" :style="{'width': itemWidth + 'px', 'height': itemHeight + 'px'}">
    </div>
</template>
<script>
export default {
    data() {
        return {
            clientWidth: 0,
            clientHeight: 0,
            timer: null,
            currentTop: 0,
            left: 0,
            top: 0,
			floatButton:''
        }
    },
    props: {
        itemWidth: {            // 悬浮按钮宽度
            type: Number,
            default: 70
        },
        itemHeight: {           // 悬浮按钮高度
            type: Number,
            default: 70
        },
        gapWidth: {             // 距离左右两边距离     
            type: Number,
            default: 10
        },
        coefficientHeight: {    // 从上到下距离比例
            type: Number,
            default: 0.55
        }
    },
    created() {
        this.clientWidth = document.documentElement.clientWidth
        this.clientHeight = document.documentElement.clientHeight
        this.left = this.clientWidth - this.itemWidth - this.gapWidth
        this.top = this.clientHeight - this.itemWidth - this.gapWidth - 40
    },
    mounted() {
		this.floatButton = this.$refs.floatButton
    },
    methods: {
        onBtnClicked(){
			console.log('onBtnClicked')
            this.$emit("onFloatBtnClicked")
        },
        handleScrollStart() {
            this.timer && clearTimeout(this.timer)
            this.timer = setTimeout(() => {
                this.handleScrollEnd()
            }, 300)
            this.currentTop = document.documentElement.scrollTop || document.body.scrollTop
            if(this.left > this.clientWidth / 2) {
                this.left = this.clientWidth - this.itemWidth / 2
            } else {
                this.left = -this.itemWidth / 2
            }
        },
        handleScrollEnd(){
            let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
            if(scrollTop === this.currentTop) {
                if(this.left > this.clientWidth/2) {
                    this.left = this.clientWidth - this.itemWidth - this.gapWidth
                } else {
                    this.left = this.gapWidth
                }
                clearTimeout(this.timer)
            }
        },
		touchStart() {
			this.floatButton.style.transition = 'none'
			document.body.style.overflow = 'hidden'
		},
		touchmove(e) {
			if (e.targetTouches.length === 1) {         // 一根手指
			    let touch = e.targetTouches[0]
			    this.left = touch.clientX - (this.itemWidth/2)
			    this.top = touch.clientY - (this.itemWidth/2)
			}
		},
		touchend() {
			document.body.style.overflow = 'auto'
			this.floatButton.style.transition = 'all 0.3s'
			if(this.left > document.documentElement.clientWidth / 2) {
			    this.left = document.documentElement.clientWidth - this.itemWidth- this.gapWidth
			}else{
			    this.left = 0 + this.gapWidth
			}
			if(this.top>(document.documentElement.clientHeight-this.itemWidth)) {
				this.top = document.documentElement.clientHeight-this.itemWidth- this.gapWidth
			}
			if(this.top<this.itemWidth) {
				this.top = 0 + this.gapWidth
			}
		},
    },
}
</script>


你可能感兴趣的:(前端开发,vue,js,javascript,vue.js,前端)