RBk
RBk

Reputation: 189

What is the error in my function for parallax scrolling?

I'm trying to get some divs to scroll with a different speed than the rest of the page to create a parallax effect.

Here's my JS and HTML:

<div class="container">
    <div class="background">
        <img src="http://placehold.it/150x150/" />
    </div>
    <div class="background">
        <img src="http://placehold.it/150x150" />
    </div>
    <div class="foreground">
        <img src="http://placehold.it/100x100" />
    </div>
    <div class="foreground">
        <img src="http://placehold.it/100x100" />
    </div>
</div>
$(document).ready(function () {
    $('.container>div').each(function () {
        var iniPos = parseInt($(this).css('top'));
        var bgspeed = 0.5; //background speed
        var fgspeed = 0.8; //foreground speed
        var speed;
        if ($(this).attr('class') == 'foreground') speed = fgspeed;
        else speed = bgspeed;
        $(window).scroll(function parallax(iniPos, speed) {
            var top = $(window).scrollTop();
            var pos = iniPos + speed * top;
            $(this).css('top', pos + 'px');
        });
    });
});

(Fiddle)

But the divs all just scroll with the same speed as the rest of the page, and I'm unable to find out why the new top positions aren't being set.

Upvotes: 0

Views: 167

Answers (1)

Siguza
Siguza

Reputation: 23840

Two reasons:

  1. Inside your parallax, this refers to window, so $(this).css() is meaningless.
    You need to define another variable outside the parallax function, inside the .each(), like

    var that = this;
    

    and then use $(that) inside parallax.

  2. By defining iniPos and speed as function arguments:

    function parallax(iniPos, speed)
    

    you break those values. iniPos will hold the value of a scroll Event, and speed will be undefined.
    Just omit the two parameters, like

    function parallax()
    

    (You can omit the function name as well, btw.)

Updated JS code:

$(document).ready(function () {
    $('.container>div').each(function () {
        var iniPos = parseInt($(this).css('top'));
        var bgspeed = 0.5; //background speed
        var fgspeed = 0.8; //foreground speed
        var speed = $(this).attr('class') == 'foreground' ? fgspeed : bgspeed;
        var that = this;
        $(window).scroll(function() {
            var top = $(window).scrollTop();
            var pos = iniPos + speed * top;
            $(that).css('top', pos + 'px');
        });
    });
});

[ Updated fiddle ]

Upvotes: 2

Related Questions