VUE screen overall scrolling - slide or wheel (native method)

16457505:


foreword

A year has passed in a blink of an eye. Year-end summaries have been very popular in recent years, so I also studied related content, mainly recording the effect of scrolling the entire screen through sliding and scrolling on the mobile phone and the computer.


1. Basic functions

Whether you use sliding or scrolling, the basic conversion logic is the same

1. Page section

First complete the construction of the page part. @mousewheel and @DOMMouseScroll are mainly to monitor the events of the scroll wheel. @touchstart, @touchend, @touchmove are touch events.

<template>
  <div class="fullPage" ref="fullPage">
    <div
        class="fullPageContainer"
        ref="fullPageContainer"
        @mousewheel="mouseWheelHandle"
        @DOMMouseScroll="mouseWheelHandle"
        @touchstart="handleTouchstart"
        @touchend="handleTouchend"
        @touchmove="handleTouchmove"
    >
      <div class="section section1">1</div>
      <div class="section section2">2</div>
      <div class="section section3">3</div>
      <div class="section section4">4</div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.fullPage {
      
      
  height: 100vh; //一定要设置,保证占满
  overflow: hidden; //一定要设置,多余的先隐藏
  background-color: rgb(189, 211, 186);
}

.fullPageContainer {
      
      
  width: 100%;
  height: 100vh;
  transition: all linear 0.5s;
}

.section {
      
      
  width: 100%;
  height: 100vh;
  background-position: center center;
  background-repeat: no-repeat;
}

//下面的只是为了区分每个页面的背景颜色
.section1 {
      
      
  background-color: rgb(189, 211, 186);
}

.section2 {
      
      
  background-color: rgb(44, 48, 43);
}

.section3 {
      
      
  background-color: rgb(116, 104, 109);
}

.section4 {
      
      
  background-color: rgb(201, 202, 157);
}
</style>

2. Functions used for page switching

global variable

 data() {
    
    
    return {
    
    
      fullpage: {
    
    
        current: 1, // 当前的页面编号
        isScrolling: false, // 是否在滚动,是为了防止滚动多页,需要通过一个变量来控制是否滚动
        deltaY: 0 // 返回鼠标滚轮的垂直滚动量,保存的鼠标滚动事件的deleteY,用来判断是往下还是往上滚
      },
      startTime: undefined, // 记录触摸开始的时间
      startX: undefined, // 记录触摸开始的X坐标,本次主要实现的是上下滑动,所以当前坐标不做强制要求
      startY: undefined, // 记录触摸开始的Y坐标
    };
  },

actual scrolling method

	// 滚动事件
    move(index) {
    
    
      this.fullpage.isScrolling = true; // 为了防止滚动多页,需要通过一个变量来控制是否滚动
      this.directToMove(index); //执行滚动
      setTimeout(() => {
    
      //这里的动画是1s执行完,使用setTimeout延迟1s后解锁
        this.fullpage.isScrolling = false;
      }, 1010);
    },
	// 执行滚动
    directToMove(index) {
    
    
      let height = this.$refs["fullPage"].clientHeight; //获取屏幕的宽度
      let scrollPage = this.$refs["fullPageContainer"]; // 获取执行tarnsform的元素
      let scrollHeight; // 计算滚动的告诉,是往上滚还往下滚
      scrollHeight = -(index - 1) * height + "px";
      scrollPage.style.transform = `translateY(${
      
      scrollHeight})`;
      this.fullpage.current = index;
    }

Switch event up and down

	// 往下切换
    next() {
    
    
      let len = 4; // 页面的个数
      if (this.fullpage.current + 1 <= len) {
    
     // 如果当前页面编号+1 小于总个数,则可以执行向下滑动
        this.fullpage.current += 1; // 页面+1
        this.move(this.fullpage.current); // 执行切换
      }
    },
    // 往上切换
    pre() {
    
    
      if (this.fullpage.current - 1 > 0) {
    
     // 如果当前页面编号-1 大于0,则可以执行向下滑动
        this.fullpage.current -= 1;// 页面+1
        this.move(this.fullpage.current);// 执行切换
      }
    },

Second, the mouse wheel control to achieve switching

 	// 监听鼠标监听
    mouseWheelHandle(event) {
    
    
      // 添加冒泡阻止
      let evt = event || window.event;
      if (evt.stopPropagation) {
    
    
        evt.stopPropagation();
      } else {
    
    
        evt.returnValue = false;
      }
      if (this.fullpage.isScrolling) {
    
     // 判断是否可以滚动
        return false;
      }
      let e = event.originalEvent || event;
      this.fullpage.deltaY = e.deltaY || e.detail; // Firefox使用detail
      if (this.fullpage.deltaY > 0) {
    
    
        this.next();
      } else if (this.fullpage.deltaY < 0) {
    
    
        this.pre();
      }
    },

3. Switching by touch on the mobile terminal

Touch events are more complicated than scroll events. First, remove the impact of finger sliding on the screen, otherwise white edges will easily appear and affect the visual effect. Then you need to record whether the distance moved is valid, whether the moved event is too long, etc...

// 清除触摸事件
    handleTouchmove(event) {
    
    
      event.preventDefault()
    },
    //手指按下屏幕
    handleTouchstart(event) {
    
    
      this.startTime = Date.now()
      this.startX = event.changedTouches[0].clientX
      this.startY = event.changedTouches[0].clientY
    },
    //手指离开屏幕
    handleTouchend(event) {
    
    
      const endTime = Date.now()
      const endX = event.changedTouches[0].clientX
      const endY = event.changedTouches[0].clientY
      //判断按下的时长
      if (endTime - this.startTime > 2000) {
    
    
        return
      }
      //滑动的方向
      let direction = "";
      //先判断用户滑动的距离,是否合法,合法:判断滑动的方向 注意 距离要加上绝对值
      if (Math.abs(endY - this.startY) > 10) {
    
    
        //滑动方向
        direction = endY - this.startY > 0 ? "down" : "up"
      } else {
    
    
        return
      }
      //用户做了合法的滑动操作
      // console.log('方向'+direction)
      if (direction === 'up') {
    
    
        this.next();
      }
      if (direction === 'down') {
    
    
        this.pre();
      }
    }

Summarize

Finally, paste all the page files for easy handling.

<template>
  <div class="fullPage" ref="fullPage">
    <div
        class="fullPageContainer"
        ref="fullPageContainer"
        @mousewheel="mouseWheelHandle"
        @DOMMouseScroll="mouseWheelHandle"
        @touchstart="handleTouchstart"
        @touchend="handleTouchend"
        @touchmove="handleTouchmove"
    >
      <div class="section section1">1</div>
      <div class="section section2">2</div>
      <div class="section section3">3</div>
      <div class="section section4">4</div>
    </div>
  </div>
</template>
<script>
export default {
  name: "Home",
  data() {
    return {
      fullpage: {
        current: 1, // 当前的页面编号
        isScrolling: false, // 是否在滚动,是为了防止滚动多页,需要通过一个变量来控制是否滚动
        deltaY: 0 // 返回鼠标滚轮的垂直滚动量,保存的鼠标滚动事件的deleteY,用来判断是往下还是往上滚
      },
      startTime: undefined, // 记录触摸开始的时间
      startX: undefined, // 记录触摸开始的X坐标,本次主要实现的是上下滑动,所以当前坐标不做强制要求
      startY: undefined, // 记录触摸开始的Y坐标
    };
  },
  methods: {
	// 往下切换
    next() {
      let len = 4; // 页面的个数
      if (this.fullpage.current + 1 <= len) { // 如果当前页面编号+1 小于总个数,则可以执行向下滑动
        this.fullpage.current += 1; // 页面+1
        this.move(this.fullpage.current); // 执行切换
      }
    },
    // 往上切换
    pre() {
      if (this.fullpage.current - 1 > 0) { // 如果当前页面编号-1 大于0,则可以执行向下滑动
        this.fullpage.current -= 1;// 页面+1
        this.move(this.fullpage.current);// 执行切换
      }
    },
    // 滚动事件
    move(index) {
      this.fullpage.isScrolling = true; // 为了防止滚动多页,需要通过一个变量来控制是否滚动
      this.directToMove(index); //执行滚动
      setTimeout(() => {  //这里的动画是1s执行完,使用setTimeout延迟1s后解锁
        this.fullpage.isScrolling = false;
      }, 1010);
    },
    // 执行滚动
    directToMove(index) {
      let height = this.$refs["fullPage"].clientHeight; //获取屏幕的宽度
      let scrollPage = this.$refs["fullPageContainer"]; // 获取执行tarnsform的元素
      let scrollHeight; // 计算滚动的告诉,是往上滚还往下滚
      scrollHeight = -(index - 1) * height + "px";
      scrollPage.style.transform = `translateY(${scrollHeight})`;
      this.fullpage.current = index;
    },
    // 监听鼠标监听
    mouseWheelHandle(event) {
      // 添加冒泡阻止
      let evt = event || window.event;
      if (evt.stopPropagation) {
        evt.stopPropagation();
      } else {
        evt.returnValue = false;
      }
      if (this.fullpage.isScrolling) { // 判断是否可以滚动
        return false;
      }
      let e = event.originalEvent || event;
      this.fullpage.deltaY = e.deltaY || e.detail; // Firefox使用detail
      if (this.fullpage.deltaY > 0) {
        this.next();
      } else if (this.fullpage.deltaY < 0) {
        this.pre();
      }
    },
    // 清除触摸事件
    handleTouchmove(event) {
      event.preventDefault()
    },
    //手指按下屏幕
    handleTouchstart(event) {
      this.startTime = Date.now()
      this.startX = event.changedTouches[0].clientX
      this.startY = event.changedTouches[0].clientY
    },
    //手指离开屏幕
    handleTouchend(event) {
      const endTime = Date.now()
      const endX = event.changedTouches[0].clientX
      const endY = event.changedTouches[0].clientY
      //判断按下的时长
      if (endTime - this.startTime > 2000) {
        return
      }
      //滑动的方向
      let direction = "";
      //先判断用户滑动的距离,是否合法,合法:判断滑动的方向 注意 距离要加上绝对值
      if (Math.abs(endY - this.startY) > 10) {
        //滑动方向
        direction = endY - this.startY > 0 ? "down" : "up"
      } else {
        return
      }
      //用户做了合法的滑动操作
      // console.log('方向'+direction)
      if (direction === 'up') {
        this.next();
      }
      if (direction === 'down') {
        this.pre();
      }
    }
  }
};
</script>
<style scoped lang="scss">
.fullPage {
  height: 100vh; //一定要设置,保证占满
  overflow: hidden; //一定要设置,多余的先隐藏
  background-color: rgb(189, 211, 186);
}

.fullPageContainer {
  width: 100%;
  height: 100vh;
  transition: all linear 0.5s;
}

.section {
  width: 100%;
  height: 100vh;
  background-position: center center;
  background-repeat: no-repeat;
}

.section1 {
  background-color: rgb(189, 211, 186);
}

.section2 {
  background-color: rgb(44, 48, 43);
}

.section3 {
  background-color: rgb(116, 104, 109);
}

.section4 {
  background-color: rgb(201, 202, 157);
}
</style>

Guess you like

Origin blog.csdn.net/YIGE_MO/article/details/128646078