滑动提示条算法

239 阅读1分钟

在这里插入图片描述

需求

项目需求中会有滑块,滑块下有提示条(滑动上面的内容,下面的提示对应滑动
在这里插入图片描述

草稿

设计一个功能不能盲目地敲代码,实现理解思路该怎么走,下面是我的思路图和相对应的字段(a:屏幕的宽度/b:滚动内容的宽度/c:滚动条的长度/d:滚动条背景的长度
在这里插入图片描述
监听触摸:
在这里插入图片描述

实例:解析

xxx.vue

<template>
    <div class="hot_slider">
      <div class="hot_slider_content">
        <div class="hot_content_inner">
          <a class="inner_items">
            <img src="xxx.png" />
            <span>京东</span>
          </a>
          <a class="inner_items">
            <img src="yyy.png" />
            <span>淘宝</span>
          </a>
            ------------------
        </div>
      </div>
      <!-- 滑动条 -->
      <div class="hot_slider_bottom">
        <div class="hot_slider_bottom_inner" :style="innerBarStyle"></div>
      </div>
    </div>
</template>

<script>
  export default {
    name:"Xxx",
    data(){
          return {
            // 1、获取屏幕的宽度a
            screenW: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
            // 2、滚动内容的宽度b
            scrollContentW: 720,
            // 3、滚动条的长度c
            barXWidth: 0,
            // 4、滚动条背景的长度d
            bgBarW: 100,
            // 5、起点
            startX: 0,
            // 6、记录结束点
            endFlag: 0,
            // 7、移动的距离
            barMoveWidth: 0
          }
        },
        //监听barXWidth样式的变化
        computed:{
          innerBarStyle(){
            return {
              width: `${this.barXWidth}px`,
              left: `${this.barMoveWidth}px`
            }
          }
        },
        mounted() {
           this.getBottomBarWidth();
           this.bindEvent();
        },
        methods:{
          // 获取滚动条的长度
          getBottomBarWidth(){
            this.barXWidth = this.bgBarW * (this.screenW / this.scrollContentW)
          },
          // 移动端事件监听
          bindEvent(){
             this.$el.addEventListener('touchstart',this.handleTouchStart,false);
             this.$el.addEventListener('touchmove',this.handleTouchMove,false);
             this.$el.addEventListener('touchend',this.handleTouchEnd,false);
          },
          // 开始触摸
          handleTouchStart(event){
             // console.log(event.touches);
             // 1、获取第一个触点
            let touch = event.touches[0];
             // 2、求出起始点
            this.startX = Number(touch.pageX);
            // console.log(this.startX);
          },
          // 开始移动
          handleTouchMove(){
            // console.log('开始移动');
            // 1、获取第一个触点
            let touch = event.touches[0];
            // 2、求出移动的距离
            let moveWidth = Number(touch.pageX) - this.startX;
            // console.log(moveWidth);
            // 3、求出滚动条走的距离
            this.barMoveWidth = -((this.bgBarW / this.scrollContentW) * moveWidth - this.endFlag)
            // 4、 边界值处理
            if(this.barMoveWidth <= 0){ // 左边
              this.barMoveWidth = 0;
            }else if(this.barMoveWidth >= this.bgBarW - this.barXWidth){ // 右边
              this.barMoveWidth = this.bgBarW - this.barXWidth;
            }
          },
          // 结束触摸
          handleTouchEnd(){
            console.log('结束触摸');
            this.endFlag = this.barMoveWidth;
          },
        }
      }
</script>

<style scoped>
  .hot_slider{
      width: 100%;
      height: 160px;
      position: relative;
      background-color: #FFFFFF;
      padding-bottom: 8px;
    }
  .hot_slider_content{
    width: 100&;
    overflow-x: scroll;
  }
  .hot_content_inner{
    width: 720px;
    height: 180px;
    display: flex;
    flex-wrap:wrap;/* 一行显示不下去自动化 */
  }
  .inner_items{
    width: 90px;
    height: 90px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    font-size: 14px;
    color: #666666;
  }
  .inner_items img{
    width: 40%;
    margin-bottom: 5px;
  }
/* 禁用原生活动条 */
 .hot_slider_content::-webkit-scrollbar{
   display: none;
 }
  .hot_slider_bottom{
    width: 100px;
    height: 3px;
    background-color: #EEEEEE;
    position: absolute;
    left: 50%;
    margin-left: -50px;
    bottom: -6px;
  }
  .hot_slider_bottom_inner{
    position: absolute;
    left: 0;
    height: 100%;
    background-color: brown;
    width: 0;
  }
</style>

总结

养成先打草稿再设计的好习惯。
继续温习样式的动态绑定和移动端触摸事件的监听流程。