scrollTo代替锚点定位并且通过scroll事件让滚动时导航栏始终可见

a标签有一个锚点定位,用到了#符号,这个定位会影响到路由,所以可以用一个scrollTo方法代替
scrollTo() 方法可把内容滚动到指定的坐标。
语法:

winodw.scrollTo(x,y)

html页面布局

<div class = "banner"></div>
  <!-- navBox固定定位 -->
  <div class = "preHeight" style="height: 80px;width: 100%"></div>
  <div class="navBox">
    <div class = "navigation-bar">
      <a class="active">模块一</a>
      <a>模块二</a>
      <a>模块三</a>
      <a>模块四</a>
      <a>模块五</a>
      <a>模块六</a>
    </div>
  </div>
  <div class="contain">
    <div id = 'm1'></div>
    <div id = 'm2'></div>
    <div id = 'm3'></div>
    <div id = 'm4'></div>
    <div id = 'm5'></div>
    <div id = 'm6'></div>
  </div>

首先
我们设置scrollTop为滚动条到窗口顶端的距离

const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop

接着
我们需要点击a标签,让元素滚动到指定的坐标
此时我们需要获取元素顶端距离浏览器窗口的高度

这里有四种高度:

  • offsetTop:返回当前元素的上边界到它的包含元素的上边界的偏移量,以像素为单位。offsetTop是相对于离它最近的具有绝对或相对定位的父级元素的距离
    offsetY则是一个鼠标事件的值,它是相对于你所点击的那个元素的左上角的Y坐标
  • scrollHeight, scrollWidth
    返回元素的完整的高度和宽度,以像素为单位。
    当一个元素拥有滚动条时,当你把滚动条滚到底部的时候,scrollHeight = scrollTop + clientHeight;
  • offsetHeight 和 offsetWidth
    只是报告元素的可见部分的大小。
    当没有滚动条时scrollHeight = clientHeight,IE则是等于内容的高度;
  • scrollTop, scrollLeft
    设置或返回已经滚动到元素的左边界或上边界的像素数。只有在元素有滚动条的时候这些像素才有用。这些属性也只在文档的 <body> 或 <html> 标记上定义(这和浏览器有关),并且一起来制定滚动文档的位置。注意,这些属性并不会指定一个 <iframe> 标记的滚动量。这是非标准的但却得到很好支持的属性

我们如何利用这些高度呢?

  • 如果你的元素的高度是固定的
window.addEventListener('scroll', ()=>{
     //在外面设置scrollTop是无效的
      const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
      //打印滚动条距浏览器顶部高度
      console.log(scrollTop)
})

当用户滚动指定的元素时,会发生 scroll 事件。
scroll 事件适用于所有可滚动的元素和 window 对象(浏览器窗口)。
我们可以通过scroll事件,让滚动浏览器的滚动条时实时显示滚动条距离页面顶端的距离,而当元素顶端移动到你想它在的位置时的scrollTop就是你想得到的元素顶部距浏览器窗口距离

  • 如果你的元素的高度不固定,就需要累加offsetTop
    我设计的页面中,需要移动的元素的父元素是body
const height1 = document.getElementById('m1').offsetTop
const height2 = document.getElementById('m2').offsetTop
const height3 = document.getElementById('m3').offsetTop
const height4 = document.getElementById('m4').offsetTop
const height5 = document.getElementById('m5').offsetTop
const height6 = document.getElementById('m6').offsetTop

首先要完成的功能是:点击导航栏中的a标签,a标签变色(加上active的样式),并且a标签对应的模块出现在导航栏的a标签下面
使用的方法:window.scrollTo(x,y)

   const navbar = document.querySelector('.navBox')
   const btns = document.querySelector('.navigation-bar').children
   navbar.addEventListener('click',e => {
      let btn = e.target
     //点击导航栏中的某个a标签,该a标签变色
      if(btn.nodeName === "A"){
        for(let i=0; i<btns.length; i++){
          if (btn === btns[i]){
            btns[i].className="active"
          }else{
            btns[i].className=""
          }
        }
        let element
        //60px为导航栏高度
        switch (btn.innerHTML) {
          case '模块一':
            element = height1 - 60
            break
          case '模块二':
            element = height2 - 60
            break
          case '模块三':
            element = height3 - 60
            break
          case '模块四':
            element = height4 - 60
            break
          case '模块五':
            element = height5 - 60
            break
          default:
            element = height6 - 60
            break
        }
       //跳转到指定位置
        window.scrollTo(0, element)
      }
    })

紧接着要完成第二个功能:元素滚动到指定位置,对应的a标签变色
在[h1,h2)内,btn的颜色变色

function handleScroll(h1,h2,btn){
      const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
      if (scrollTop < h2 && scrollTop >= h1) {
        let title = btn
        for (let i = 0; i < btns.length; i++){
          if (title === btns[i].innerHTML){
            btns[i].className = 'active'
          }else{
            btns[i].className = ''
          }
        }
      }
    }

我们可以在发生scroll事件时使用该方法,同时保持导航栏一直在可视范围内

window.addEventListener('scroll', ()=>{
      const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
      //滚动条距浏览器顶部高度
      console.log(scrollTop)
      //保持导航栏一直在视窗顶部
      if(scrollTop>=400){
        navbar.style.position = 'fixed'
        navbar.style.top = '0'
      }else{
        navbar.style.position = 'absolute'
        navbar.style.top = '400px'
      }
      //滚动条滚动,导航栏颜色随之切换
      handleScroll(0,height2-100,'模块一')
      handleScroll(height2-100,height3-100,'模块二')
      handleScroll(height3-100,height4-100,'模块三')
      handleScroll(height4-100,height5-100,'模块四')
      handleScroll(height5-100,height6-150,'模块五')
      handleScroll(height6-150,height6+document.getElementById('m6').clientHeight,'模块六')
      console.log(height6-150)
    })

完整代码:
https://github.com/evaSpec/scroller

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容