I have a dialog box appearing when user clicks on any of the flat.
What I want to do is to lock scrollbar if viewport height is bigger than 550px. Now I apply overflow:hidden to body, but this causes site jumping when scrollbar is hiding. I want to disable scrolling, but still show a scrollbar. Is it possible?
Thanks in advance!
You can simulate a scrollbar lock by detecting the scroll, and scrolling back to the previous position.. (this might appear jerky on some browsers especially if you drag the scroll bar itself)
function lockScroll() {
var lockX = window.scrollX;
var lockY = window.scrollY;
function lockIt() {
window.scrollTo(lockX,lockY);
return false;
}
window.addEventListener("scroll",lockIt,false)
return {
stop: function(){
window.removeEventListener("scroll",lockIt,false)
}
}
}
Usage:
var locker = lockScroll(); // locks scrolling
And when you're done you can re-enable scrolling
locker.stop(); // unlocks scrolling
Related
So I started off with having a problem on mobile phones where I had a div over the main page and whenever I scrolled on that div I would also be scrolling the whole page. I found a fix for this problem from this post as follows:
var $layer = $("#layer");
$layer.bind('touchstart', function (ev) {
var $this = $(this);
var layer = $layer.get(0);
if ($this.scrollTop() === 0) $this.scrollTop(1);
var scrollTop = layer.scrollTop;
var scrollHeight = layer.scrollHeight;
var offsetHeight = layer.offsetHeight;
var contentHeight = scrollHeight - offsetHeight;
if (contentHeight == scrollTop) $this.scrollTop(scrollTop-1);
});
This fixed the problem for me but also created another problem. This fix makes the scrolling seem less seamless. Usually when you scroll on a page the page itself sometimes scrolls a little bit past the page based on the speed of the users swipe. Any ideas on how to make this a smoother scroll.
-webkit-overflow-scrolling: touch; will allow content continues to scroll for a while after finishing the scroll gesture and removing your finger from the touchscreen. The speed and duration of the continued scrolling is proportional to how vigorous the scroll gesture was. You can read more here
So add this line of code to the CSS of the div:
-webkit-overflow-scrolling: touch;
This should give you smoother scrolling.
I have a popup window in my site that show additional information about the elements been show in the main screen. I need to syncronize the scrolling between the two windows, in a way that when the user scroll one of the window , the other window is automatticaly scrolled in the same ammount.
I was able to do that using jquery scroll event, and using the scrollTop function to set the scroll position. something like this:
$("#localDiv").scroll(function() {
var scrollPos = $("#localDiv").scrollTop();
$("targetElement").scrollTop( scrollPos );
});
I've simplified the actual code, because I have to do some work to reach the elements in another window, but this is not the question.
The problem is, this code works fine in Chrome and IE, but in FireFox the scrolling gets really slow.
I've created an example here : http://jsfiddle.net/Lv2dw787/4/. The problem seems to ocurr with DIV's in the same page as well. You can note that when the scrolling syncing is disabled, the speed turn back to normal.
Does anyone have a clue on how to fix this on FireFox?
Edit after Dave Chen answer:
The accepted answer solved my problem, but it has a catch. I first tried to do this:
lock = true;
try {
var scrollPos = $("#contentDivA").scrollTop();
$("#contentDivB").scrollTop( scrollPos );
}
finally
{
lock = false;
}
But the $("#contentDivB").scrollTop( scrollPos ); line seems to generate a scroll event on divB only after the current function finishes executing, so the finally part of try..finally was executing before that. So I had to this:
lock = true;
var scrollPos = $("#contentDivA").scrollTop();
$("#contentDivB").scrollTop( scrollPos );
and on DivB scroll event:
if (lock)
lock = false;
else {
(Do the scroll on DivA)
}
The reason is because of two reasons:
Firefox does smoothing on its scrolling
jQuery's scrollTop will trigger events
Let's look at some pseudo-code:
When divA is scrolled -> scroll divB to the same spot
When divB is scrolled -> scroll divA to the same spot
The problem is that when you scroll divA or divB to the same spot, it will also cause the when to happen again.
So for example, when you scroll divA, this is what happens:
scroll divA -> scroll divB to the same spot -> scroll divA to the same spot
This causes divA to stick to the same spot after scrolling a little, and thus what causes the sluggish effect in firefox.
A solution is to ignore scrolling events when you scroll:
$(document).ready(function() {
var ignore = false;
$("#contentDivA").scroll(function() {
var tmpIgnore = ignore;
ignore = false;
if (!tmpIgnore && $("#chkSyncEnabled")[0].checked)
{
var scrollPos = $("#contentDivA").scrollTop();
scrollTop($("#contentDivB"), scrollPos);
}
});
$("#contentDivB").scroll(function() {
var tmpIgnore = ignore;
ignore = false;
if (!tmpIgnore && $("#chkSyncEnabled")[0].checked)
{
console.log("here");
var scrollPos = $("#contentDivB").scrollTop();
scrollTop($("#contentDivA"), scrollPos);
}
});
function scrollTop(el, position) {
ignore = true;
el.scrollTop(position);
}
});
Example
I have some trouble when trying to back to the top of a list.
I put -webkit-overflow-scrolling:touch on the list to get momentum scroll.
However when I'm using jQuery scrollTop(); while the momentum scroll is still going, it jumps to the top but it doesn't stop the momentum. So it keeps going down again until the momentum ends.
Is there an easy way to stop momentum scroll?
Set your list's -webkit-overflow-scrolling style to 'auto' and then back to 'touch' after a short timeout.
i.e.
let scrollContainer = document.getElementById('yourListId');
scrollContainer.style['-webkit-overflow-scrolling'] = 'auto'; // stop scroll
setTimeout(function() {
scrollContainer.scrollTop = 0; // or jQuery scrollTop()
scrollContainer.style['-webkit-overflow-scrolling'] = 'touch'; // re-enable
}, 2);
Reference: this SO answer. (modified their implementation to get rid of scrollbar redraw jerkiness on desktop browsers)
I have a big navigation bar that I want to hide everytime the scroll bar is not at the top position.
So basically, I have the idea of having two navigation bar, overlapping each other.
One with the larger height is on top (having a larger z-index) and the smaller one with the same navigation but with a small width is below it.
I want something that when the user scrolls his mouse wheel down/ drags the scroll bar, use a keyboard to scroll down even a little, the big navigation bar will disappear (more like hide), leaving the smaller one on top.
I did a trick that the one with higher height is scrollable (not fixed) and the one below is fixed.
But I find it awkward. So instead, I want to hide it when the user scrolls down and show it again when the scroll bar is at the top.
Basically, it's like a windows taskbar in autohide mode. But it will hide when the user scrolls down and show when the scroll bar is on top :))
You can use some simple JS to do this:
window.onscroll = function() {
var top = document.body.scrollTop + document.documentElement.scrollTop == 0;
document.getElementById('topbar').style.display = top ? 'block' : 'none';
document.getElementById('scollbar').style.display = top ? 'none' : 'block';
};
Substitute IDs as relevant to your code.
Here is a simple jQuery function that will show or hide a element <ElementID> in this case dependant on the scrollTop position.
$(function () {
$(window).scroll(function () {
if ($(this).scrollTop() == 0) {
$('#<ElementID>').show();
} else {
$('#<ElementID>').hide();
}
});
})
fiddle: http://jsfiddle.net/DerNalia/88N4d/9/
The behavior I'm trying to accomplish:
The Sidebar(s) should be fixed on the page if there is enough room
for them
The Sidebar(s) should scroll if there is ever not enough room for them
When scrolling down, and the bottom of the sidebar(s) is reached, it should stop scrolling
When scrolling down, the sidebar(s) should also scroll down, until
the bottom of the sidebar(s) is/are reached
When scrolling up, and the top of the sidebar(s) is reached, it should stop scrolling
If at any point during the scrolling of the content, the user switches directions of scrolling, the sidebar(s) shall also move in the same direction as the rest of the page / content
When scrolling up, the sidebar(s) should also scroll up, until the
top of the sidebar(s) is/are reached
If the content is shorter than the sidebar(s), the sidebar(s) should
still be able to scroll This is the one that I'm having trouble
with
How do I make it so that I can detect the intended scroll distance desired by the user, rather than use the actual scrolled distance of the content body? There may be another solution, but this is all I can think of for right now.
I'm currently using Chrome on Mac.
UPDATE:
something I've noticed: using the track pad on macs does the stretching / bouncy scrolling shenanigans on the edges.. which messes up this javascript hard core. It's possible to scroll the sidebar completely off the screen if you bounce up enough times. Mouse Wheel scrolling does not have this issue.
I think you’d be much better off positioning the columns absolute and then check positions onscroll and toggle the positions.
It gets quite complicated, since the scroll will jump if both columns are fixed and the content has regular flow.
I created a solution for you using a simpler logic that goes:
var $win = $(window);
var $containers = $(".container").css('position','absolute');
// we need to force a height to the body for fixed positioning
$('body').css('minHeight', Math.max.apply( Math, $containers.map(function() {
return $(this).height();
})));
$win.bind("resize scroll", function() {
var scrolled = $win.scrollTop(),
winheight = $win.height(),
elheight = 0;
$containers.each(function() {
elheight = $(this).height();
$(this).css('position', function() {
if ( elheight > (winheight+scrolled) ) {
$(this).css('top',0);
return 'absolute';
}
$(this).css('top', Math.min(0, winheight-elheight));
return 'fixed';
});
});
});
It should fill your requirements. The fixed positioning kicks in if the columns are shorter than the window height, or if the scrollTop is enough.
A demo in all it’s glory: http://jsfiddle.net/mb9qC/