简体   繁体   中英

Bug in Chrome & Safari where adding a sticky fixed class to nav when scrolling down makes it scroll to the top

I am currently trying to make my own bootstrap sticky nav function and it works perfect on all browsers except Safari and Chrome. For some reason when the javascript adds the "sticky" class with "position:fixed; top:0;", it automatically jumps up to the top of the window when you scroll by dragging the browser's side bar. If I scroll with my mouse it's fine also.

<style>
* {font-family:arial;margin:0;padding:0;}
p{border:1px solid #000; height:500px;}
.logo, .intro, .menu, .content { padding:10px;}
.content {margin-top:10px;}
.menu-padding {padding-top:40px;}
.content p {margin-bottom:20px;}
.menu {background:#eee;color:#000;line-height:30px;letter-spacing:1px;width:100%; border-bottom:1px solid #e9e9e9; }
.sticky {position:fixed;top:0;}
</style>
<div>
    <div class="logo"><h1>Header or something</h1></div>
    <div class="intro"><h3>... or whatever</h3></div>
    <div class="menu">home | services | contact</div>
</div>
<div class="content">
    <p>1</p>
    <p>2</p>
    <p>3</p>
    <p>4</p>
    <p>5</p>
</div>
<script>
jQuery(document).ready(function () {
    var menu = jQuery('.menu');
    var origOffsetY = menu.offset().top;
    function scroll() {
        if (jQuery(window).scrollTop() >= origOffsetY) {
            jQuery('.menu').addClass('sticky');
        } else {
            jQuery('.menu').removeClass('sticky');
        }
    }
    document.onscroll = scroll;
});
</script>

I also put add jQuery to my header. If I scroll down with my mouse and hit refresh it doesn't jump to the top. It's only when I use the browser's side scroll. Anyone else notice this or should I just try a different method? Thank you.

EDIT

Also when I drag the browser's scroll bar down, the scroll function freezes as it jumps to the top of the page. I can still be holding down the click button after this happens moving up and down and no scroll occurs. If I let go then I can scroll again but then the cycle begins again. I've also replaced those addclass/removeclass with just jQuery CSS actions and the same thing happened. It like freaks out when "fixed" applies during the scroll.

Your code depends solely on this conditional...

var origOffsetY = menu.offset().top;
...
    if (jQuery(window).scrollTop() >= origOffsetY) { ...

Looking at the jQuery documentation...

.scrollTop() - "Returns: Integer" .

.offset() - "The numbers returned by dimensions-related APIs, including .offset() , may be fractional in some cases. Code should not assume it is an integer ."

So if you cannot depend on .offset().top to always return an integer, cases exist where your conditional will fail. To test this theory, you could put a console.log inside your function so you can inspect the value of origOffsetY while it's "freaking out" ...

function scroll() {
    console.log(origOffsetY);  // <- log the value into your console
    if (jQuery(window).scrollTop() >= origOffsetY) {
        ....

DEMO: http://jsfiddle.net/nx83mtbe/show

FWIW, your code is working fine in my Safari (Mac v6.1.6) and my Chrome (Mac v37.0.2062.94).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM