前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue css 滚动楼层导航定位

vue css 滚动楼层导航定位

作者头像
solate
发布2021-03-05 10:58:19
3K0
发布2021-03-05 10:58:19
举报
文章被收录于专栏:solate 杂货铺

理解滚动图

左右结构

代码语言:javascript
复制
<template>
  <div>
    <div class="floor-nav">
      <ul class="nav-list">
        <li
            class="nav-list-item"
            v-for="(item, index) in floorList"
            :key="item.id"
            @click="setFloorNavMountClick(index)"
        >{{ item.name }}</li>
      </ul>
    </div>
    <div class="wrap-body">
      <div
          class="floor-item"
          v-for="item in floorList"
          :key="item.id">
        <div class="floor-item-box">
          <h3>{{ item.name }}</h3>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'IFloor',
  data () {
    return {
      element: {
        nav_item: null,
        floor_item: null
      },
      timer: null,
      floorList: [
        { id: 1, name: 'F1' },
        { id: 2, name: 'F2' },
        { id: 3, name: 'F3' },
        { id: 4, name: 'F4' },
        { id: 5, name: 'F5' },
        { id: 6, name: 'F6' }
      ],
      navItemIndex: 0,
    }
  },
  mounted () {
    this.element = {
      nav_item: document.getElementsByClassName('nav-list-item'),
      floor_item: document.getElementsByClassName('floor-item')
    }
    this.element.nav_item[0].classList.add('active')
    // window.addEventListener('scroll', this.floorSrcollEventListener)
  },
  beforeDestroy () {
    // window.removeEventListener('scroll', this.floorSrcollEventListener)
  },
  methods: {
    /**
     * 根据下标改变菜单样式
     * @param {Number} index  楼层下标
     */
    changeNavClass(index) {
      this.element.nav_item[this.navItemIndex].classList.remove('active');
      this.element.nav_item[index].classList.remove('active');
      this.navItemIndex = index;
    },

    /**
     * 设置楼层导航事件驱动方法
     * @param {Number} index  楼层下标
     */
    setFloorNavMountClick (index) {
      const { floor_item } = this.element
      const floor_offsetTop = floor_item[index].offsetTop - floor_item[0].offsetTop,
          window_scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
          timer = {
            step: 60,
            times: 16,
            FLOOR_OFFSETTOP: floor_offsetTop,
          }
      if (window_scrollTop > floor_offsetTop) {
        this.setFloorScrollArrowUp(timer)
      } else if (window_scrollTop == floor_offsetTop) {
        return false
      } else {
        this.setFloorScrollArrowDown(timer)
      }
    },
    /**
     * 设置楼层向上滚动
     * @param {Object} timer 定时器配置
     */
    setFloorScrollArrowUp (timer) {
      clearInterval(this.timer)
      this.timer = setInterval(() => {
        let window_scrollTop = document.documentElement.scrollTop || document.body.scrollTop
        if (window_scrollTop <= timer.FLOOR_OFFSETTOP) {
          document.documentElement.scrollTop = timer.FLOOR_OFFSETTOP
          document.body.scrollTop = timer.FLOOR_OFFSETTOP
          clearInterval(this.timer)
        } else {
          document.documentElement.scrollTop = window_scrollTop - timer.step
          document.body.scrollTop = window_scrollTop - timer.step
        }
      }, timer.times)
    },
    /**
     * 设置楼层向下滚动
     * @param {Object} timer 定时器配置
     */
    setFloorScrollArrowDown (timer) {
      clearInterval(this.timer)
      this.timer = setInterval(() => {
        let window_scrollTop = document.documentElement.scrollTop || document.body.scrollTop
        // 这里多加了一个大一点的值,需要精确的就这里自己算一下,我随便写了个500,
        // 不加会导致window_scrollTop一直小于timer.FLOOR_OFFSETTOP,
        // 退出不了setInterval,导致滑动失效一直在底部。
        if (window_scrollTop + 500 >= timer.FLOOR_OFFSETTOP) {
          document.documentElement.scrollTop = timer.FLOOR_OFFSETTOP
          document.body.scrollTop = timer.FLOOR_OFFSETTOP
          clearInterval(this.timer)
        } else {
          document.documentElement.scrollTop = window_scrollTop + timer.step
          document.body.scrollTop = window_scrollTop - timer.step
        }
      }, timer.times)
    },
    // /**
    //  * 监听窗口滚动楼层导航动态定位
    //  */
    // floorSrcollEventListener () {
    //   const { nav_item, floor_item } = this.element
    //   const window_scrollTop = document.documentElement.scrollTop || document.body.scrollTop
    //   for (let i = 0, len = floor_item.length; i < len; i++) {
    //     let floor_offsetTop = floor_item[i].offsetTop - floor_item[0].offsetTop
    //     if (window_scrollTop >= floor_offsetTop) {
    //       for (let n = 0, len = nav_item.length; n < len; n++) {
    //         const current_classList = nav_item[n].classList
    //         i === n
    //             ? current_classList.add('active')
    //             : current_classList.remove('active')
    //       }
    //     }
    //   }
    // }
  }
}
</script>

<style scoped>
.floor-warpper {
  width: 1000px;
  margin: auto;
}
.floor-nav {
  /*position: fixed;*/
  float: left;
  width: 100px;
}
.nav-list {
  width: 100%;
  padding: 0;
  display: inline-block;
  text-align: center;
  /*background-color: #f8f8f8;*/
}
.nav-list-item {
  display: inline-block;
  width: 100%;
  height: 100%;
  line-height: 48px;
  vertical-align: middle;
  align-self: center;
  border-bottom: 1px solid #fff;
  cursor: pointer;
}
.nav-list-item.active,
.nav-list-item:hover {
  /*color: #FFF;*/
  background-color: #C9C9C9;
}
.wrap-body {
  margin-left: 120px;
  border-left: dashed #1c1c1c 1px;
}
.floor-item {
  margin-left: 20px;
  width: 95%;
  /*margin: 60px auto;*/
  min-height: 300px;
  text-align: center;
  color: #FFF;
  background-color: #404040;
}
</style>

原左边固定不变

代码语言:javascript
复制
<template>
  <div class="floor-warpper">
    <section class="floor-nav" id="floorNavList">
      <ul class="nav-list">
        <li
            class="nav-list-item"
            v-for="(item, index) in floorList"
            :key="item.id"
            @click="setFloorNavMountClick(index)"
        >{{ item.name }}</li>
      </ul>
    </section>
    <section
        class="floor-item"
        v-for="item in floorList"
        :key="item.id">
      <div class="floor-item-box">
        <h3>{{ item.name }}</h3>
      </div>
    </section>
  </div>
</template>

<script>
export default {
  name: 'IFloor',
  data () {
    return {
      element: {
        nav_item: null,
        floor_item: null
      },
      timer: null,
      floorList: [
        { id: 1, name: 'F1' },
        { id: 2, name: 'F2' },
        { id: 3, name: 'F3' },
        { id: 4, name: 'F4' },
        { id: 5, name: 'F5' },
        { id: 6, name: 'F6' }
      ]
    }
  },
  mounted () {
    this.element = {
      nav_item: document.getElementsByClassName('nav-list-item'),
      floor_item: document.getElementsByClassName('floor-item')
    }
    this.element.nav_item[0].classList.add('active')
    window.addEventListener('scroll', this.floorSrcollEventListener)
  },
  beforeDestroy () {
    window.removeEventListener('scroll', this.floorSrcollEventListener)
  },
  methods: {
    /**
     * 设置楼层导航事件驱动方法
     * @param {Number} index  楼层下标
     */
    setFloorNavMountClick (index) {
      const { floor_item } = this.element
      const floor_offsetTop = floor_item[index].offsetTop - floor_item[0].offsetTop,
          window_scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
          timer = {
            step: 60,
            times: 16,
            FLOOR_OFFSETTOP: floor_offsetTop,
          }
      if (window_scrollTop > floor_offsetTop) {
        this.setFloorScrollArrowUp(timer)
      } else if (window_scrollTop == floor_offsetTop) {
        return false
      } else {
        this.setFloorScrollArrowDown(timer)
      }
    },
    /**
     * 设置楼层向上滚动
     * @param {Object} timer 定时器配置
     */
    setFloorScrollArrowUp (timer) {
      clearInterval(this.timer)
      this.timer = setInterval(() => {
        let window_scrollTop = document.documentElement.scrollTop || document.body.scrollTop
        if (window_scrollTop <= timer.FLOOR_OFFSETTOP) {
          document.documentElement.scrollTop = timer.FLOOR_OFFSETTOP
          document.body.scrollTop = timer.FLOOR_OFFSETTOP
          clearInterval(this.timer)
        } else {
          document.documentElement.scrollTop = window_scrollTop - timer.step
          document.body.scrollTop = window_scrollTop - timer.step
        }
      }, timer.times)
    },
    /**
     * 设置楼层向下滚动
     * @param {Object} timer 定时器配置
     */
    setFloorScrollArrowDown (timer) {
      clearInterval(this.timer)
      this.timer = setInterval(() => {
        let window_scrollTop = document.documentElement.scrollTop || document.body.scrollTop
        if (window_scrollTop + 500 >= timer.FLOOR_OFFSETTOP) {
          document.documentElement.scrollTop = timer.FLOOR_OFFSETTOP
          document.body.scrollTop = timer.FLOOR_OFFSETTOP
          clearInterval(this.timer)
        } else {
          document.documentElement.scrollTop = window_scrollTop + timer.step
          document.body.scrollTop = window_scrollTop - timer.step
        }
      }, timer.times)
    },
    /**
     * 监听窗口滚动楼层导航动态定位
     */
    floorSrcollEventListener () {
      const { nav_item, floor_item } = this.element
      const window_scrollTop = document.documentElement.scrollTop || document.body.scrollTop
      for (let i = 0, len = floor_item.length; i < len; i++) {
        let floor_offsetTop = floor_item[i].offsetTop - floor_item[0].offsetTop
        if (window_scrollTop >= floor_offsetTop) {
          for (let n = 0, len = nav_item.length; n < len; n++) {
            const current_classList = nav_item[n].classList
            i === n
                ? current_classList.add('active')
                : current_classList.remove('active')
          }
        }
      }
    }
  }
}
</script>

<style scoped>
.floor-warpper {
  width: 1000px;
  margin: auto;
}
.floor-nav {
  position: fixed;
  top: 200px;
  left: 50px;
}
.nav-list {
  width: 48px;
  padding: 0;
  display: inline-block;
  text-align: center;
  background-color: #f8f8f8;
}
.nav-list-item {
  display: inline-block;
  width: 100%;
  height: 100%;
  line-height: 48px;
  vertical-align: middle;
  align-self: center;
  border-bottom: 1px solid #fff;
  cursor: pointer;
}
.nav-list-item.active,
.nav-list-item:hover {
  color: #FFF;
  background-color: #404040;
}

.floor-item {
  width: 100%;
  margin: 60px auto;
  min-height: 300px;
  text-align: center;
  color: #FFF;
  background-color: #404040;
}
</style>

参考

滚动楼层导航定位

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 理解滚动图
  • 左右结构
  • 原左边固定不变
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档