The Background:
I am trying to create a system that allows to scroll through a kind of map using mouse scroll up and mouse scroll down like so:
-------
| |
| 1 |
| |
-------
------- ------- ------- -------
| | | | | | | |
| 2 | | 3 | | 4 | | 5 |
| | | | | | | |
------- ------- ------- -------
-------
| |
| 6 |
| |
-------
Each of the boxes above is reset in javascript to be the height and width of the browser. When you scroll your mouse up and down, the browser will scroll to the equal position in the map, starting with div 1, and then 2, and so on. This positioning is set via my scroll funciton, which listenes for mouse scrolls and adds the appropriate padding to the top and margin to the left to create the illusion of the map above.
Here is the codepen to it:
And here is the javascript to it:
$(function(){
$(window).on('resize', function(){
var $divs = $('.vertical, .horizontal > div'),
ww = $(this).width(),
wh = $(this).height();
$divs.css({
height : wh,
width : ww
});
$('.horizontal').each(function(){
var $container = $(this),
nbChildren = $container.children().length;
posY = $container.offset().top,
$container.css({
height: ww*(nbChildren-1) + wh,
width: ww*(nbChildren)
});
});
}).trigger('resize');
$(window).on('scroll', function(){
var wh = $(window).height(),
scroolTop = $(window).scrollTop();
$('.horizontal').each(function(){
var $container = $(this),
posY = $container.offset().top,
height = $container.height(),
nbChildren = $container.children().length,
marginMax = $container.width()/nbChildren*(nbChildren-1),
marginL = scroolTop - posY;
if(marginL<0) marginL = 0;
else if (marginL>marginMax) marginL = marginMax;
$container.css('marginLeft', -marginL);
$container.css('paddingTop', marginL);
});
}).trigger('scroll');
});
The Problem:
Resizing the window creates a weird div offset that fixes itself when the scroll function is called for divs 2 to 5. On resizing when in those divs, they seem to offset themselves and then only get fixed when the scroll function is called.
.trigger('resize'); should always be called, yes? I dont know why it only gets called when the scroll function is made.
How can this be remedied?
The Background:
I am trying to create a system that allows to scroll through a kind of map using mouse scroll up and mouse scroll down like so:
-------
| |
| 1 |
| |
-------
------- ------- ------- -------
| | | | | | | |
| 2 | | 3 | | 4 | | 5 |
| | | | | | | |
------- ------- ------- -------
-------
| |
| 6 |
| |
-------
Each of the boxes above is reset in javascript to be the height and width of the browser. When you scroll your mouse up and down, the browser will scroll to the equal position in the map, starting with div 1, and then 2, and so on. This positioning is set via my scroll funciton, which listenes for mouse scrolls and adds the appropriate padding to the top and margin to the left to create the illusion of the map above.
Here is the codepen to it:
http://codepen.io/lorenzoi/pen/mxejJ
And here is the javascript to it:
$(function(){
$(window).on('resize', function(){
var $divs = $('.vertical, .horizontal > div'),
ww = $(this).width(),
wh = $(this).height();
$divs.css({
height : wh,
width : ww
});
$('.horizontal').each(function(){
var $container = $(this),
nbChildren = $container.children().length;
posY = $container.offset().top,
$container.css({
height: ww*(nbChildren-1) + wh,
width: ww*(nbChildren)
});
});
}).trigger('resize');
$(window).on('scroll', function(){
var wh = $(window).height(),
scroolTop = $(window).scrollTop();
$('.horizontal').each(function(){
var $container = $(this),
posY = $container.offset().top,
height = $container.height(),
nbChildren = $container.children().length,
marginMax = $container.width()/nbChildren*(nbChildren-1),
marginL = scroolTop - posY;
if(marginL<0) marginL = 0;
else if (marginL>marginMax) marginL = marginMax;
$container.css('marginLeft', -marginL);
$container.css('paddingTop', marginL);
});
}).trigger('scroll');
});
The Problem:
Resizing the window creates a weird div offset that fixes itself when the scroll function is called for divs 2 to 5. On resizing when in those divs, they seem to offset themselves and then only get fixed when the scroll function is called.
.trigger('resize'); should always be called, yes? I dont know why it only gets called when the scroll function is made.
How can this be remedied?
Share Improve this question edited Apr 22, 2013 at 18:48 lorenzoid asked Apr 19, 2013 at 19:27 lorenzoidlorenzoid 1,83210 gold badges34 silver badges51 bronze badges 2- debounce is probably what you are after github./cowboy/jquery-throttle-debounce – epascarello Commented Apr 19, 2013 at 19:31
- The resize event is being called correctly. The problem lies in your code, not in the dispatch. – diego nunes Commented Apr 29, 2013 at 0:43
3 Answers
Reset to default 3 +25Using a timer should just be enough:
$(function(){
var timeoutResize;
$(window).on('resize', function(){
clearTimeout(timeoutResize);
timeoutResize = setTimeout(function(){
var $divs = $('.vertical, .horizontal > div'),
ww = $(this).width(),
wh = $(this).height();
$divs.css({
height : wh,
width : ww
});
$('.horizontal').each(function(){
var $container = $(this),
nbChildren = $container.children().length;
posY = $container.offset().top,
$container.css({
height: ww*(nbChildren-1) + wh,
width: ww*(nbChildren)
});
});
},100);
}).trigger('resize');
...
});
. . You need to consider that whenever a user resize the window vertically, the scroll position will be affected and it should also affect your background scrolling (because it is based on the current scroll position).
. . The simplest fix will be simply call $(window).trigger('scroll');
at the end of the resize handler code, so you keep it DRY. I made this change on my CodePen fork. Check it out.
If you have an event handler that is running too frequently, you can throttle it like this:
function throttle(ms, fn) {
var allow = true;
function enable() {
allow = true;
}
return function(e) {
if (allow) {
allow = false;
setTimeout(enable, ms);
fn.call(this, e);
}
}
}
Then pass your handler to throttle
when you assign it. It'll return a function that'll run at most once every n
milliseconds, based on the first argument you provide.
$(window).resize(throttle(100, function(e) {
// do heavy work
}));