Reputation: 850
i'm trying to implement such a feature:
webpage has two columns. narrow left one - with menu and some info, and wide right one - with the main content of page. height of the left column is much smaller than the right's one
so when user scrolls down the webpage and the left narrow column is already above the viewport, it gets hidden giving extra width for right column.
after i hide the left column i should scroll browser's window little bit upper in order to corresponding element on the right gets placed on the top of viewport (it jumps upper when i hide the left col, because the width of right col gets increased)
i've implemented this, but the problem is in smooth scrolling in all modern browsers. when you press down
key or page down
or mousewheel
or use your finger in touch-devices, browser generates a lot of scroll
-events during one scroll.
it looks like this:
scrollTop == 500
scrollTop == 520
scrollTop == 530
scrollTop == 535
scrollTop == 537
and the moment when my script realises that left col should get hidden corresponds to scrollTop of 500, and at this very moment my script tries to set scroll top to the new value, but it gets instantly overridden by following browser smoothscroll events:
scrollTop == 500 //browser
scrollTop == 450 //mine! i need to save this position!
scrollTop == 520 //browser
scrollTop == 530 //browser
scrollTop == 535 //browser
scrollTop == 537 //browser
so how can i cancel all changes of scrollTop below?
this is my code if needed:
$(function() {
//height of left column
window.main_left_height1 = $('#main_left_div').height();
var ar = $.grep($('.page_container > div'), function(item) {
return $(item).position().top >= window.main_left_height1;
});
//anchor element on the right which placed on the same height with the end of left col
window.main_left_anchor = ar[0];
//we will toggle left column on this scroll height
window.main_left_height1 = $(window.main_left_anchor).position().top;
window.main_left_state = true;
window.ignore_scroll = false;
window.ignore_scroll_value = -1;
});
if (is_mobile || true)
{
$(window).scroll(function(e) {
var scroll_top = $(this).scrollTop();
//i've tried to ignore browser scrolling after i set its value manually in the script but this doesn't work
if (window.ignore_scroll)
{
if (Math.abs(window.ignore_scroll_value - scroll_top) < 50)
{
window.ignore_scroll = false;
window.ignore_scroll_value = -1;
return true;
}
e.preventDefault();
return false;
}
if (window.main_left_state)
{
if (window.main_left_height1 && scroll_top >= window.main_left_height1)
{
$('#main_left').hide();
window.main_left_state = false;
if (!window.main_left_height2)
window.main_left_height2 = $(window.main_left_anchor).position().top;
window.ignore_scroll = true;
window.ignore_scroll_value = window.main_left_height2;
$(this).scrollTop(window.main_left_height2);
}
}
else
{
if (window.main_left_height2 && scroll_top < window.main_left_height2)
{
$('#main_left').show();
window.main_left_state = true;
window.ignore_scroll = true;
window.ignore_scroll_value = window.main_left_height1;
$(this).scrollTop(window.main_left_height1);
}
}
});
}
any suggestions? thanks!
Upvotes: 0
Views: 1381
Reputation: 7445
As I see since browser got input (like mouse scroll or key press) and scroll event is generated you can do nothing with it. If events are generated window will be scrolled and if even there will be page rearrangement scroll offset wouldn't be changed. It means you will have jumpy scrolling if you will change scrollTop value after.
Try to change your right column position (Top) and not scrollTop. For example, when user scrolls down and you calculated that scrollTop need to be changed for -60px, just add those 60px to your right panel's top (you can even animate it). I think it might help.
And the second suggestion is to handle mouse and keyboard input by your self to generate scrolling, like it is done here: How to disable scrolling temporarily? (NIGHTMARE! I think :))
Upvotes: 1