vue实现滚动鼠标滚轮切换页面,类似于纵向走马灯、满屏滚动

新项目产品被甲方的要求逼疯了,大概返稿了100+次吧,最后甲方网上找了个他们认为的比较有科技感的模板,让我们照着写,首页就是类似于纵向走马灯,鼠标滚动切换,一次切换一整屏的效果。之前没接触过,写了个简单的demo,仅作为学习笔记。

其实原理很简单,就是把所有页面放在一个div中,然后滚动的时候改变外层div的top即可。

因为滚动条监听事件是实时的,所以要加上节流来防止页面切换太快速,我这控制在1.5s才能切换一页。

其实vue不应该操作dom,应该用数据来渲染虚拟dom,但是有些地方暂时没找到合适的方法,还是用的dom操作。

2021-09-26补充:推荐使用满屏滚动插件:GitHub - alvarotrigo/fullPage.js: fullPage plugin by Alvaro Trigo. Create full screen pages fast and simple

<template>
    <div id="wrap" :style="{ height: screenHeight + 'px' }">
        <div id="main" :style="{ top: nowTop + 'px' }">
            <ul id="pageUl" type="circle">
                <li id="pageUlLi1" class="pageUlLi" :class="{'active': curIndex == 1}">&nbsp;</li>
                <li id="pageUlLi2" class="pageUlLi" :class="{'active': curIndex == 2}">&nbsp;</li>
                <li id="pageUlLi3" class="pageUlLi" :class="{'active': curIndex == 3}">&nbsp;</li>
                <li id="pageUlLi4" class="pageUlLi" :class="{'active': curIndex == 4}">&nbsp;</li>
                <li id="pageUlLi5" class="pageUlLi" :class="{'active': curIndex == 5}">&nbsp;</li>
            </ul>
            <div style="background-color: #1b6d85" id="page1" class="page"></div>
            <div style="background-color: #5cb85c" id="page2" class="page"></div>
            <div style="background-color: #8a6d3b" id="page3" class="page"></div>
            <div style="background-color: #337ab7" id="page4" class="page"></div>
            <div style="background-color: #66512c" id="page5" class="page"></div>
        </div>
    </div>
</template>

<script>
    
    export default {
        name: 'Home',
        data(){
            return{
                screenWeight: 0,        // 屏幕宽度
                screenHeight: 0,        // 屏幕高度
                index: 1,               // 用于判断翻页
                curIndex: 1,            // 当前页的index
                startTime: 0,           // 翻屏起始时间  
                endTime: 0,             // 上一次翻屏结束时间
                nowTop: 0,              // 翻屏后top的位置
                pageNum: 0,             // 一共有多少页
                main: Object,
                obj: Object
            }
        },
        mounted(){
            this.screenWeight = document.documentElement.clientWidth;
            this.screenHeight = document.documentElement.clientHeight;
            this.main = document.getElementById("main");
            this.obj = document.getElementsByTagName("div");
            for (let i = 0; i < this.obj.length; i++) {
                if (this.obj[i].className == 'page') {
                    this.obj[i].style.height = this.screenHeight + "px";
                }
            }
            this.pageNum = document.querySelectorAll(".page").length;

            // 浏览器兼容      
            if ((navigator.userAgent.toLowerCase().indexOf("firefox") != -1)) {
                document.addEventListener("DOMMouseScroll", this.scrollFun, false);
            } else if (document.addEventListener) {
                document.addEventListener("mousewheel", this.scrollFun, false);
            } else if (document.attachEvent) {
                document.attachEvent("onmousewheel", this.scrollFun);
            } else {
                document.onmousewheel = this.scrollFun;
            }
        },
        methods:{
            scrollFun(event) {
                this.startTime = new Date().getTime();
                // mousewheel事件中的 “event.wheelDelta” 属性值:返回的如果是正值说明滚轮是向上滚动
                // DOMMouseScroll事件中的 “event.detail” 属性值:返回的如果是负值说明滚轮是向上滚动
                let delta = event.detail || (-event.wheelDelta);
                // 如果当前滚动开始时间和上次滚动结束时间的差值小于1.5s,则不执行翻页动作,这样做是为了实现类似节流的效果
                if ((this.startTime - this.endTime) > 1500) {
                    if (delta > 0 && parseInt(this.main.offsetTop) >= -(this.screenHeight * (this.pageNum - 2))) {
                        // 向下滚动
                        this.index++;
                        this.toPage(this.index);
                    }else if (delta < 0 && parseInt(this.main.offsetTop) < 0) {
                        // 向上滚动
                        this.index--;
                        this.toPage(this.index);
                    }
                    // 本次翻页结束,记录结束时间,用于下次判断
                    this.endTime = new Date().getTime();
                }
            },
            // 翻页
            toPage(index) {
                if (index != this.curIndex) {
                    let delta = index - this.curIndex;
                    this.nowTop = this.nowTop - delta * this.screenHeight;
                    this.curIndex = index;
                }
            }
        }
    }
</script>
<style>
    html, body {
        height: 100%;
    }

    body, ul, li, a, p, div {
        /*慎删*/
        padding: 0px;
        margin: 0px;
    }

    #wrap {
        overflow: hidden;
        width: 100%;
    }

    #main {
        position: relative;
        transition:top 1.5s;
    }

    .page {
        /*谨删*/
        width: 100%;
        margin: 0;
    }

    #pageUl {
        position: fixed;
        right: 10px;
        bottom: 50%;
    }

    .active{
        color: red;
    }
</style>

  • 15
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值