0

I am new to scripting.

Okay, so I am creating single-paged website (alturl.com/3ovx5) having several DIVs with 100% width/height stacked on top of one another. The fixed buttons on the top animate the page to scroll to the top-of-the-desired-DIV and the button is then highlighted by detecting scrollTop.


Now I am trying to put in a feature similar to http://www.morethanamap.com/developer-stories/ .. This page responds to mouse-scroll and scrolls to the next/previous DIV automatically, something beyond my league.

Using this code I tried the following:

$(document).ready(function() {

var top0 = $('#page0').position().top;
var top1 = $('#page1').position().top;
// and so on

var oldst = 0; // for OLD-scrollTop

$(document).bind('scroll', function () {
var newst = $(this).scrollTop(); // NEW-scrollTop
 if (newst > oldst) { // user scrolls down
        if (newst < top1) { $('body').animate({scrollTop: top1}, 435); }
   else if (newst > top1 && newst < top2) { $('body').animate({scrollTop: top2}, 435); }
   else if (newst > top2 && newst < top3) { $('body').animate({scrollTop: top3}, 435); }
   else if (newst > top6 && newst < top7) { $('body').animate({scrollTop: top7}, 435); } // and so on
      }
 else { // user scrolls up
        if (newst > top1 && newst < top2) { $('body').animate({scrollTop: top0}, 435); }     
   else if (newst > top2 && newst < top3) { $('body').animate({scrollTop: top1}, 435); }
   else if (newst > top7 || newst = top7) { $('body').animate({scrollTop: top6}, 435); } // and so on
      }
oldst = newst; //update OLD-scrollTop
 });
});


The landing-DIV scrolls down okay, but after that the scroll stops working, and instead the page starts jumping up and down. I guessed there might be a clash in the argument. So, I change the arguments to detect the highlighted (anchor IDed one/two/three....) button, and then scroll up/down accordingly.

New argument becomes:

if (newst > oldst) { 
     if (newst < top1) { $('html, body').animate({scrollTop: top1}, 435); }
else if ($('#one').hasClass('selected')) { $('body').animate({scrollTop: top2}, 435); }
else if ($('#two').hasClass('selected')) { $('body').animate({scrollTop: top3}, 435); }
else if ($('#three').hasClass('selected')) { $('body').animate({scrollTop: top4}, 435); } // and so on
    }

SAME result. Scroll fails after a single go.

Here is the first demo (alturl.com/rizw3) which detects scrollTop.
Here is the second demo (alturl.com/44wp4) which detects highlighted buttons.

HERE is a test (alturl.com/v6sr7) that uses alert-messages to show that the arguments (using the code from first demo) are working fine. However, what I wanna do is disable scrollbar once it is accomplished so, it should be either scroll to DIV above, or DIV below (like the google-maps example).

Hope there is a better way, to work this out? :/

Thanks loads!

Community
  • 1
  • 1
a4aLien
  • 25
  • 10
  • Sorry about the non-linked URLs. stackoverflow wont allow me to use more than 2 since I'm new here. – a4aLien Dec 04 '13 at 03:23
  • You might look into [One Page Scroll](http://www.thepetedesign.com/demos/onepage_scroll_demo.html) – Zach Saucier Dec 04 '13 at 05:01
  • Thanks Zach! One-page scroll is great but unfortunately, I can't use it with my site this time because my menu is supposed to scroll up and lock, but with One-page scroll, it cant. Not unless I alter the code a good way. :( – a4aLien Dec 05 '13 at 22:25
  • You only have to comment out the `if(next.length < 1) {` part in [the js](https://github.com/peachananr/onepage-scroll/blob/master/jquery.onepage-scroll.js) (line 149) – Zach Saucier Dec 05 '13 at 23:26
  • 1
    Nah, theres a better plugin to use in my case, Just found it http://guidobouman.github.io/jquery-panelsnap/ Thank you Zach :) – a4aLien Jan 01 '14 at 04:10

1 Answers1

0

I see what you are trying to do, somewhat anchoring it to a fixed point on scroll.

Then it's not going to be smooth handling it with scroll() function alone because dragging the scrollbar can be a big problem (it's going to be jumpy/jerky), I suggest you do the anchoring with mousewheel event only.

In this solution we are using 'anchored' class as the indicator.

$(document).on('mousewheel DOMMouseScroll', function(e) {
    var $anchored = $('div.anchored'), 
         delta = e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? 1 : -1;   

    if(delta < 0) { 
        //mousewheel down
        $next = $anchored.next();

        if($next.length){
            $('body, html').stop().animate({scrollTop:$next.offset().top},'slow');     
        } 
    }else{ 
        //mousewheel up
        $prev = $anchored.prev();

        if($prev.length){
            $('body, html').stop().animate({scrollTop:$prev.offset().top},'slow');    
        }
    }
    e.preventDefault();
});

Now if the user scrolls by dragging the scrollbar you also need to move the 'anchored' class indicator to the most visible <div> in viewport.

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

$('div').each(function(){
    var offset = $(this).offset();
    if(st >= offset.top && st < offset.top + $(this).outerHeight()){
        $(this).addClass('anchored');
    }else{
        $(this).removeClass('anchored');
    }
});

});

See this jsfiddle.

Mark S
  • 3,789
  • 3
  • 19
  • 33
  • I've updated the answer to work on cross-browsers. I had fun doing this so I also made one with a navigation :D. Check this [**jsfiddle**](http://jsfiddle.net/mark_s/9bZGd/) – Mark S Dec 04 '13 at 10:06
  • <3 :D You rock man. Wish I could understand what is really happening in the script :/ I am having PROBLEMS trying to use it in my site :| My 'section' are nested inside #page-wrap, called .page They're all given 100% heights of their parents, including body & html. Yet, when I try your script my mousewheel just stops scrolling. I recon its the $body = $('body, html') part, which, when removed allows only mousewheel-down to function (not as intended). In your fiddle, I've tried wrapping your divs in #page-wrap, and naming your divs to '.page' (and changing the code paths), it works fine. :( – a4aLien Dec 05 '13 at 22:23
  • Thank you :D. Actually this solution is preventing the default `mousewheel` scrolling functions, and binding a new anchor scrolling functions. `$('body, html').stop().animate()` is the anchoring method, `$('body')` alone will work on chrome but not on firefox, so for x-browsers we animate both 'body' and 'html'. Can you also create a jsfiddle and add your markup and css so I can help you find the problem. – Mark S Dec 06 '13 at 04:30
  • Sorry for been gone this long. Thank you for your 'Excellent' solution (that was composed in minutes) :) But I found a plugin called Jquery-PanelSnap by Guido Bouman. Excellent work there too! Thanks once again Mark :) – a4aLien Jan 01 '14 at 04:09