patternjavascriptMinor
jQuery parallax site (on scroll)
Viewed 0 times
parallaxscrolljquerysite
Problem
I have this code for a website I'm working on. It uses
```
$(function() {
// Tell the DOM that JS is enabled
$('html').removeClass('no-js');
// Navigation Waypoints
$('.waypoint').waypoint(function(event, d) {
var a = $(this);
if (d === "up") a = a.prev();
if (!a.length) a = a.end();
$('.active').removeClass('active');
a.addClass('active');
$('a[href=#'+a.attr('id')+']').addClass('active');
}, {offset: '40%'});
// Parallax Effects
$(window).scroll(function() {
var s = $(window).scrollTop(),
b = ($('body').height()/100)*20;
$('.container').each(function () {
$(this).css('top', Math.round((($(this).closest('.waypoint').offset().top-s)+b)/$(this).attr('data-speed')));
});
$('#home hgroup').css('bottom', '-'+Math.round(s/6)+'px');
});
// FAQs
$(document).on('click', '.faqs a', function () {
$('.faqs .open').slideToggle().removeClass('open');
$(this).siblings().slideToggle('fast').addClass('open');
return false;
});
// Kinetics
$('.counter').kinetic({
y: false
});
// Smooth Scroll
$(document).on('click', 'nav a', function() {
var t = $($(this).attr('href')),
o = t.offset().top,
b = ($('body').height()/100)*10;
if($(this).attr('href') === "#home") {
$('html, body').animate({scrollTop: o}, 'slow');
} else {
$('html, body').animate({scrollTop: o+b}, 'slow');
}
return false;
});
// Set Margin
function setMargin () {
var t = $('#about'),
o = t.offset().top,
c = $('.container'),
b = ($('body').height()/100)*20,
m = Math.round(parseInt(t.css('margin-top')))
window.scroll events to parallax some items. It's running a bit slow on average machines. Is there any way I could improve it to make it run faster?```
$(function() {
// Tell the DOM that JS is enabled
$('html').removeClass('no-js');
// Navigation Waypoints
$('.waypoint').waypoint(function(event, d) {
var a = $(this);
if (d === "up") a = a.prev();
if (!a.length) a = a.end();
$('.active').removeClass('active');
a.addClass('active');
$('a[href=#'+a.attr('id')+']').addClass('active');
}, {offset: '40%'});
// Parallax Effects
$(window).scroll(function() {
var s = $(window).scrollTop(),
b = ($('body').height()/100)*20;
$('.container').each(function () {
$(this).css('top', Math.round((($(this).closest('.waypoint').offset().top-s)+b)/$(this).attr('data-speed')));
});
$('#home hgroup').css('bottom', '-'+Math.round(s/6)+'px');
});
// FAQs
$(document).on('click', '.faqs a', function () {
$('.faqs .open').slideToggle().removeClass('open');
$(this).siblings().slideToggle('fast').addClass('open');
return false;
});
// Kinetics
$('.counter').kinetic({
y: false
});
// Smooth Scroll
$(document).on('click', 'nav a', function() {
var t = $($(this).attr('href')),
o = t.offset().top,
b = ($('body').height()/100)*10;
if($(this).attr('href') === "#home") {
$('html, body').animate({scrollTop: o}, 'slow');
} else {
$('html, body').animate({scrollTop: o+b}, 'slow');
}
return false;
});
// Set Margin
function setMargin () {
var t = $('#about'),
o = t.offset().top,
c = $('.container'),
b = ($('body').height()/100)*20,
m = Math.round(parseInt(t.css('margin-top')))
Solution
The jQuery documentation offers the best advice:
Event performance
In most cases, an event such as
Obviously it would be ideal if you could move the calculations outside the event handler to reach the desired performance, but that may not be possible in this case. So to expand on the rate-limiting approach, there are 2 ways you could go about it:
-
Call event handler after the user has finished scrolling (hasn't scrolled for some set amount of time):
-
Call event handler immediately after scrolling, with a minimum delay between scroll events:
Event performance
In most cases, an event such as
click occurs infrequently and performance is not a significant concern. However, high frequency events such as mousemove or scroll can fire dozens of times per second, and in those cases it becomes more important to use events judiciously. Performance can be increased by reducing the amount of work done in the handler itself, caching information needed by the handler rather than recalculating it, or by rate-limiting the number of actual page updates using setTimeout.Obviously it would be ideal if you could move the calculations outside the event handler to reach the desired performance, but that may not be possible in this case. So to expand on the rate-limiting approach, there are 2 ways you could go about it:
-
Call event handler after the user has finished scrolling (hasn't scrolled for some set amount of time):
var timer = null;
$(window).scroll(function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function() {
timer = null;
// your event handling logic here
}, 50);
});-
Call event handler immediately after scrolling, with a minimum delay between scroll events:
var justExecuted = false;
$(window).scroll(function() {
if(justExecuted) {
return;
}
// your event handling logic here
justExecuted = true;
setTimeout(function() {
justExecuted = false;
}, 50);
});Code Snippets
var timer = null;
$(window).scroll(function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function() {
timer = null;
// your event handling logic here
}, 50);
});var justExecuted = false;
$(window).scroll(function() {
if(justExecuted) {
return;
}
// your event handling logic here
justExecuted = true;
setTimeout(function() {
justExecuted = false;
}, 50);
});Context
StackExchange Code Review Q#19610, answer score: 6
Revisions (0)
No revisions yet.