javascript - 利用滚动监听回到顶部的时候,吸附在顶端的导航栏会抖一下,请问是什么原因?

查看:82
本文介绍了javascript - 利用滚动监听回到顶部的时候,吸附在顶端的导航栏会抖一下,请问是什么原因?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style>
    * {margin: 0;padding: 0;box-sizing: border-box;}
    ul {list-style: none;width: 100%;height: 50px;background: #212121;padding-left: 100px;}
    li {display: inline-block;line-height: 50px;width: 100px;text-align: center;background: #333;color: #FFF;cursor: pointer;}
    p {height: 400px;width: 80%;background: #DDD;margin: 0 auto;border: 1px solid #000;}
    .fix {position: fixed;top: 0;width: 100%;}
    .cur {background: #FFF; color: #212121;}
</style>
<body>
    <div style="height: 200px;"></div>
    <nav id="nav">
        <ul>
            <li class="cur">1</li><!--
         --><li>2</li><!--
         --><li>3</li>
        </ul>
    </nav>
    <div>
        <p>1</p>
        <p>2</p>
        <p>3</p>
    </div>
    <div style="height:500px;"></div>
</body>
<script>

function up() {
var nav = document.getElementById("nav")
var scroll = document.documentElement
var top = nav.offsetTop
var hei = nav.offsetHeight
var li = document.getElementsByTagName("li")
var p = document.getElementsByTagName("p")
    window.onscroll = function() {
        if (scroll.scrollTop >= top) {
            nav.className = "fix"
        }
        if (scroll.scrollTop <= top) {
            nav.className = ""
        }
        for (var i=0;i<li.length;i++) {
            if (scroll.scrollTop + hei >= p[i].offsetTop - top/1.1) {
                for (var j=0;j<li.length;j++) {
                    li[j].className = ""
                }
                li[i].className = "cur"
            }
        }
    }
}

function move(){
    var nav = document.getElementById("nav")
    var scroll = document.documentElement
    var hei = nav.offsetHeight
    var li = document.getElementsByTagName("li")
    var p = document.getElementsByTagName("p")
    for (var i=0; i<li.length; i++){
        var timer
        li[i].index = i
        li[i].onclick = function(){
            var self = this
            clearInterval(timer)
            timer = setInterval(function(){
                if (scroll.scrollTop + hei <= p[self.index].offsetTop) {
                    scroll.scrollTop += Math.ceil(p[self.index].offsetTop/10)
                if (scroll.scrollTop + hei >= p[self.index].offsetTop) {
                    scroll.scrollTop = p[self.index].offsetTop - hei
                    clearInterval(timer)
                }
                } else {
                    scroll.scrollTop /= 1.1
                    if (scroll.scrollTop + hei <= p[self.index].offsetTop) {
                        scroll.scrollTop = p[self.index].offsetTop - hei
                        clearInterval(timer)
                    }
                }
            },20)
        }
    }
}

window.onload = function(){
    up()
    move()
}
</script>
</html>

点一下 3 到底部,然后点 1 返回顶部,吸附在顶端的导航栏会抖一下,看了好久不知道问题出在哪里,求教一下!
另外还想问一下关于这行代码

scroll.scrollTop /= 1.1 

为什么要除以1.1呢?

解决方案

问题解决了
原因是navbar回到顶部的时候监听的是第一个P的offsetTop,顶部空间不足就把navbar给挤下去了。
改成监听navbar自己的offsetTop,然后回到顶部时,让P给出navbar.offsetHeight的空间就解决了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style>
    *{margin: 0;padding: 0;}
    #nav {width: 100%;height: 50px;list-style: none;background: #212121;padding-left: 10%;}
    #nav li {display: inline-block;width: 100px;height: 100%;background: #333;color: #FFF;text-align: center;line-height: 50px;}
    #nav .cur {background: #BBB;color: #000;}

    p {height: 400px;border: 1px solid #000;background: #DDD;width: 80%;margin: 0 auto;}
    .fixed {position: fixed;top: 0;left: 0;}
</style>
<body>
    <div style="height:300px;"></div>
    <ul id="nav" class="">
        <li class="cur">1</li><!--
     --><li>2</li><!--
     --><li>3</li>
    </ul>
    <div id="div">
        <p>1</p>
        <p>2</p>
        <p>3</p>
    </div>
    <div style="height:500px;"></div>
</body>
<script>
    var navbar = document.getElementById("nav")
    var p = document.getElementsByTagName("p")
    var li = document.getElementsByTagName("li")
    var div = document.getElementById("div")
    var navH = navbar.offsetHeight
    var pH = navbar.offsetTop // 本来取的是第一个P的offsetTop
    window.onscroll = function() {
        var scrollTop = document.documentElement.scrollTop
        if (scrollTop >= pH ) {
            navbar.className = "fixed"
            div.style.paddingTop = navH + "px"
        } else {
            navbar.className = ""
            div.style.paddingTop = "" 
        }
        for (var i=0; i<p.length; i++){
            if (scrollTop + navH >= p[i].offsetTop/1.1) {
                for (var j=0; j<p.length; j++) {
                    li[j].className = ""
                }
                li[i].className = "cur"
            }
        }
    }
    for (var k=0; k<p.length; k++) {
        var scroll = document.documentElement
        var timer
        li[k].index = k
        li[k].onclick = function () {
            var self = this
            clearInterval(timer)
            timer = setInterval(function(){
                console.log(scroll.scrollTop)
                if (scroll.scrollTop + navH <= p[self.index].offsetTop) {
                    scroll.scrollTop += Math.ceil(p[self.index].offsetTop/10)
                    if (scroll.scrollTop + navH >= p[self.index].offsetTop) {
                        scroll.scrollTop = p[self.index].offsetTop - navH
                        clearInterval(timer) 
                    }
                } else {
                    scroll.scrollTop /= 1.5
                    if (scroll.scrollTop + navH <= p[self.index].offsetTop) {
                        scroll.scrollTop = p[self.index].offsetTop - navH
                        clearInterval(timer)
                    }
                }
            },20)
        }
    }

</script>
</html>

这篇关于javascript - 利用滚动监听回到顶部的时候,吸附在顶端的导航栏会抖一下,请问是什么原因?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆