All you really need to do to make sure that there is no jump, is to make sure you set the initial value the same way that you set it on scroll.
The best way to do this is to move your code into a function, outside of the scroll handler, and then call that function in the scroll handler instead. Then, you can also call that function any other time you might want.. like on page load.
Here's what I changed your code to:
(function ($) {
"use strict";
$('.parallax-section').each(function () {
var $el = $(this);
$(window).scroll(function () {
updateBackground($el);
});
updateBackground($el);
});
}(jQuery));
var speed = 0.4;
function updateBackground($el) {
var diff = $(window).scrollTop() - $el.offset().top;
var yPos = -(diff * speed);
var coords = '50% ' + yPos + 'px';
$el.css({
backgroundPosition: coords
});
}
See Demo
Basically, the updateBackground()
function does all the work that the scroll event was doing before. Now, on scroll, I simply call that function, and pass it the information that it needs.
Beneath that, I also immediately call the function, this way it will run on page load as well.
(note that I also moved the speed
variable outside of the .each()
, both so that it can be referenced more easily by the new function, and also because it doesn't need to get set over and over again.. it's always the same, we only really need to declare it once.)