Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript syntax help for a back to top link that appears only on scroll up

I have a page set up with a back to top link (in an entire bar) slides down at the top of the page, only on scroll up.

I'm a beginner with Javascript, so I have cobbled something together, that does work (it shows on scroll up, unless we're 500px from the top, hides on scroll down), and it uses some code I got from here to not check every pixel scrolled.

What I want to add is that even if you are still scrolling up once you get to the submenu, then the toplink should scroll off the page again - I don't need a back to the top once you are at the top.

I've gotten this to work by adding a SECOND Javascript script, but I know that there must be a much better way to get something like this to work in the first call. Also this second call uses the window.scroll function which I'm pretty sure is the wrong way to do it.

FIRST SCRIPT

// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var subMenu = $('#subMenu').offset().top;

$(window).scroll(function(event){
    didScroll = true;
});

setInterval(function() {
    if (didScroll) {
        hasScrolled();
        didScroll = false;
    }
}, 250);

function hasScrolled() {
    var st = $(this).scrollTop();

       // Make sure they scroll more than delta
    if(Math.abs(lastScrollTop - st) <= delta)
        return;

    // If they scroll down, add class .nav-up.

    if (st > lastScrollTop && st ){
        // Scroll Down
         $('#backtotop').removeClass('nav-down').addClass('nav-up');
         $(".toplink").fadeOut("fast");


    } else {
        // Scroll Up
       if(st + $(window).height() < $(document).height() && st > 500) {
        $('#backtotop').removeClass('nav-up').addClass('nav-down');
        $(".toplink").fadeIn("slow");

        } 



    }


    lastScrollTop = st;

}

SECOND SCRIPT

    <script>

   $(window).scroll (function ()
   {var st = $(this).scrollTop();
    var subMenu = $('#subMenu').offset().top;


     if (st < subMenu) {
        $('#backtotop').removeClass('nav-down').addClass('nav-up');
        $(".toplink").fadeOut("fast");


     }

     });

    </script>

Fiddle with the HTML and CSS: https://jsfiddle.net/Lu0jz3nc/11/

like image 846
Rachel Lilburn Avatar asked Apr 25 '15 00:04

Rachel Lilburn


People also ask

How do you scroll automatically to the top of the page using JavaScript?

scrollTo(): The scrollTo() method of the window Interface can be used to scroll to a specified location on the page. It accepts 2 parameters the x and y coordinate of the page to scroll to. Passing both the parameters as 0 will scroll the page to the topmost and leftmost point.

How do I make my scroll to the top?

As defined in the HTML specification, you can use href="#top" or href="#" to link to the top of the current page.


3 Answers

I've modified your jsfiddle a bit, albeit it's not the most elegant or efficient solution, it works. https://jsfiddle.net/aedm9cut/

Here is the JS:

var lastY = 0;
var subMenu = $('#subMenu').offset().top;

$(window).scroll(function(event){
    currentY = $(window).scrollTop();
    if(currentY > 500 && lastY > currentY){
           $('#backtotop').removeClass('nav-up').addClass('nav-down');
            $(".toplink").fadeIn("slow");
    }
    else{
        $('#backtotop').removeClass('nav-down').addClass('nav-up');
         $(".toplink").fadeOut("fast");
    }
    lastY = $(window).scrollTop();
});

This code does 2 things, check if you are past 500px from top and also checks the direction of your scroll. if you are past 500px and are scrolling up the bar will show, otherwise it won't.

This code can be improved so that the code in the if and else statements aren't run every time the user scrolls, but perhaps you can make a breakpoint that the code can detect the user has gone past and then run the code once. Right now, the code in the if/ or the else is run several times during a scroll event.

like image 190
Mike Hamilton Avatar answered Oct 23 '22 06:10

Mike Hamilton


You should be able to do this all in the window scroll handler, with the help of one global variable.

var MIN_DELTA = 5;
var MIN_SCROLLTOP = 500;
var MENU_HEIGHT = $('#backtotop').height();

$('#backtotop').addClass('nav-up');

var lastScrollTop = 0;
$(window).scroll(function (event) {
    var scrollTop = $(window).scrollTop();
    if (scrollTop > MENU_HEIGHT) {
        if (scrollTop < lastScrollTop) { // Scrolling up
            if (scrollTop > MIN_SCROLLTOP) {
                if (scrollTop < (lastScrollTop - MIN_DELTA)) {
                    $('#backtotop').removeClass('nav-up').addClass('nav-down');
                    $(".toplink").fadeIn("slow");
                    lastScrollTop = scrollTop;
                }
            } else {
                lastScrollTop = scrollTop;
            }
        } else { // Scrolling down
            $('#backtotop').removeClass('nav-down').addClass('nav-up');
            $(".toplink").fadeOut("fast");
            lastScrollTop = scrollTop;
        }
    } else {
        $('#backtotop').removeClass('nav-down').addClass('nav-up');
        $(".toplink").fadeOut("fast");
        lastScrollTop = scrollTop;
    }
});

Notice that the lastScrollTop variable is not updated when the window has been scrolled down, past MIN_SCROLLTOP, but it has not changed more than MIN_DELTA.

jsfiddle

like image 31
John S Avatar answered Oct 23 '22 05:10

John S


Simple, call the hasScrolled in the onclick attribute. Now I've added a special argument forceup which when true will run the special code to make it hide. So when you click the To Top button, it will force it to go up. The reason it is window.hasScrolled is to make it global.

window.hasScrolled = function (forceup) {

    if (forceup) {
        $('#backtotop').removeClass('nav-down').addClass('nav-up');
        $(".toplink").fadeOut("fast");
    }

//Rest of code
}

Fiddle

like image 45
Downgoat Avatar answered Oct 23 '22 06:10

Downgoat