jQuery: parallax scrolling with the mousewheel event

How to create a parallax scrolling effect with jQuery and the mousewheel event.

Thanks to the MouseWheel plugin we can create a smooth parallax scrolling effect with jQuery. This plugin normalizes the mousewheel event so that it can work reliably across browsers.

The markup

We create a full-screen layout with the following markup:


<body>
<div id="site">
  <div id="section-wrapper">
    <div class="section" id="section-1"></div>
    <div class="section" id="section-2"></div>
    <div class="section" id="section-3"></div>
  </div>
</div>
</body>

Then we include our scripts just before the closing body tag:


<script src="jquery.js"></script>
<script src="jquery.mousewheel.js"></script>
<script src="myscript.js"></script>
</body>
</html>

The CSS code

Our document doesn’t need to show any scrollbar so we set the overflow property to hidden. Each section must be relatively positioned to properly calculate its vertical offset and move its parent element accordingly:


html, body {
    overflow: hidden;
}

#site {
    width: 100%;
}

#section-wrapper {
    position: relative;
    width: 100%;
}

div.section {
    width: 100%;
    position: relative;
}

#section-1 {
    background: #ccc;
}

#section-2 {
    background: #666;
}

#section-3 {
    background: #000;
}
​

The jQuery code

With jQuery we first need to assign a stated height to each section by using the global window’s height. When the section container will be moved upwards or downwards using its top property we also need to give to the current section a special class so that it can be easily selected during the scrolling process:


var Parallax = {
    utils: {
        doSlide: function(section) {
            var top = section.position().top;
            $('#section-wrapper').stop().animate({
                top: -top
            }, 600, 'linear', function() {
                section.addClass('slided').siblings('div.section').removeClass('slided');
            });
        }
    },
    fn: {
        setHeights: function() {
            $('div.section').height($(window).height());
        },
        onSiteScroll: function() {
            var section = null;

            $('#section-wrapper').mousewheel(function(event, delta) {
                event.preventDefault();
                if (delta < 0) { // down
                    section = ($('.slided').length) ? $('.slided') : $('#section-1');
                    var next = (section.next().length) ? section.next() : $('#section-1');
                    Parallax.utils.doSlide(next);
                }
                else if(delta > 0) { // up
                    section = ($('.slided').length) ? $('.slided') : $('#section-1');
                    var prev = (section.prev().length) ? section.prev() : $('#section-1');
                    Parallax.utils.doSlide(prev);
                }
            });


        }
    },

    init: function() {
        for (var prop in this.fn) {
            if (typeof this.fn[prop] === 'function') {
                this.fn[prop]();
            }
        }
    }
};

Parallax.init();​

You can see the demo on this page.

Comments

Due to my tight schedules I can't handle comments on this site. You can comment this article with a message on Facebook or a tweet on Twitter. If you have problems with this article, just send me an email.