Mousewheel Sliding like Apple 5s page

988 views Asked by At

I'm new to jQuery & Javascript and I'm trying to remake the Apple 5s sliding page as you can see here: http://www.apple.com/iphone-5s/ . I'm quite far at the moment, but it doesn't stop calling the function when you rapidly scroll. What I mean by that, if you scroll down really fast with my code you basically get to the lowest slide. But at Apple its site the slide animation has to be finished before you can call the animation again. I'm having problems with realizing this. Here is my code.

HTML:

<div id="slider">
    <div id="slide1"></div>
    <div id="slide2"></div>
    <div id="slide3"></div>
</div>

jQuery:

// jQuery for Sliding
$(document).ready(function() {
    var scroll = 1;
    var currentScroll = 1;
    var totalSlides = $("#slider").children().length;
    $("#slider").children().hide();
    $("#slide1").show();
    $(window).bind('mousewheel', function(event) {
        if (event.originalEvent.wheelDelta >= 0) {
            // Scroll event up
            currentScroll = scroll;
            scroll = scroll - 1;
            if (scroll < 1) { 
                scroll = 1;
            } 
            else { 
                $("#slide" + currentScroll).hide("slide", {
                    direction : 'down'
                }, 700);
                $("#slide" + scroll).show("slide", {
                    direction : 'up'
                }, 700);
            }

        } else {
            // Scroll event down
            currentScroll = scroll;
            scroll++;
            if (scroll < totalSlides + 1) {
                $("#slide" + currentScroll).hide("slide", {
                    direction : 'up' 
                }, 700); 
                $("#slide" + scroll).show("slide", { 
                    direction : 'down'
                }, 700);  
            } 
        } 
    }); 
});

Thanks for your help!

1

There are 1 answers

2
Mark S On BEST ANSWER

On the Apple's page, it's not hiding/showing the slides it's just anchoring it to a fix point (which is the slides offset().top position) depending on mousewheel direction. Binding 'mousewheel' alone does not work on other browsers like firefox, it should be 'mousewheel DOMMouseScroll'. Furthermore 'mousewheel-down' on firefox returns a positive value on chrome it's negative value.

This should be the mousewheel event structure, cross-browser-wise:

$(window).on('mousewheel DOMMouseScroll', function(e){
    e.preventDefault();

    var delta = e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? 1 : -1;

    if(delta < 0) { 
        //mousewheel down
    }else{
        //mousewheel up
    }
});

We need to determine which slide is currently being anchored, we can add a class 'active' as the indicator. If the user's mousewheel direction is down, move to the next() slide and reassign the class 'active' on this slide. If the user user's mousewheel direction is up, move to the prev() slide of the current 'active' slide and reassign the 'active' class.

$(document).ready(function(){
$(window).on('mousewheel DOMMouseScroll', function(e){
    e.preventDefault();      
    var delta = e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? 1 : -1;
    //get the current active slide
    var $active = $('#slider > .active');

    if(delta < 0) { 
        //mousewheel down
        var $next = $active.next();
        //check if there's a next slide available
        if($next.length){
            //animate scrolling to the next slides offset top
           $('body, html').stop(true).animate({scrollTop:$next.offset().top},'slow');
           //move also the indicator class 'active'
           $next.addClass('active').siblings().removeClass('active');
        }

    }else{
        //mousewheel up
        var $prev = $active.prev();
        if($prev.length){
             //animate scrolling to the previous slides offset top
            $('body, html').stop(true).animate({scrollTop:$prev.offset().top},'slow'); 
            $prev.addClass('active').siblings().removeClass('active');
        }
    }
});  
});

See this jsfiddle.