I've got a checkScroll handler attached to a div's scroll event (soon to be implemented as a timer instead), which checks to see if the user is nearing the bottom and fetches more data to display. The UI is smooth and works well when used with the mouse scroll wheel, but when dragging the scrollbar the following occurs:
checkScroll handler determines user is near the bottom (and for example, let's say scrollTop is 800)
an AJAX request is sent in the background to fetch more data
data is returned and appended to the div
if the scrollbar is still in drag mode, but the mouse hasn't moved since the data has been appended the scrollbar has now changed size and jumped up a bit, scrollTop is still set to 800 and the data is in the same position
once the mouse is dragged 1px in any direction, the scrollbar jumps back under the mouse and all the data has shifted, the user has lost their original position
Is there a way to prevent this from happening, a la Twitter?
This is standard browser behaviour, Firefox will make the content jump but Chrome keeps the current position when increasing the scrollHeight
PS. How do you close a question as invalid?
Related
In my React application, the user is presented with a horizontally scrollable list and can scroll left / right to load more data.
When the user scrolls all the way to the left, I load more data and append it to the beginning of my list. This works fine, except that the scroll position seems to be reset to 0.
To solve this, I restore the scroll position after prepending the new data to my list. This works well on Android, but on IOS this doesn't work.
On IOS, the scrollLeft position of my DIV is still reset to 0 after rendering, even if I restore the scroll position after rendering. The strange thing seems to be that this only happens if the user was still scrolling when the rendering took place.
So it seems like on IOS Safari, setting the scrollLeft / scrollTop position of a div only works if the user is not currently scrolling that div.
Has anyone seen this before, and perhaps know a workaround?
Here is what I am trying to do: When the user is clicking a button, a transparent overlay is opening. The background shouldn't be scrollable but stay at the scroll position. So what I am doing at the moment is that once the button is clicked, I safe the current scroll position via window.scrollY, then add overflow: hidden to both the html and body tag (which unfortunately scrolls the page to the very top), then proceed to scroll to the saved position inside the main div of the website. In most browsers these steps aren't noticeable so it seems like everything just stays at the same position. In Safari however, you can see that for a few ms the background scrolls to the very top and then back again.
So what I would like to know is how to execute multiple methods at once before the DOM updates. Or maybe you can think of another way of doing this?
Thank you!
I'm having a weird bug with Angular.
Here's the context: The page loads with everything fitting in the window. The user clicks on something and a bunch more content loads. An ng-repeat pushes the document height below the fold, the vertical scrollbar appears, and the user can scroll down to view the rest of the content. Everything works.
If I scroll to the bottom, and then refresh the page, the scroll position jumps back to the top of the page and everything is reset. If I click to load the additional content again, it shows up, but the scroll is 'locked'. The scrollbar still appears, but scrolling with the scrollwheel is impossible.
All the site functionality works, but I cannot scroll down with the mouse (or using the arrow keys). If I click and drag the scrollbar down, it fixes the issue and scrolling is restored.
To make matters worse, the bug only happens about 10% of the time. The rest of the time, the page happily scrolls just fine.
Some clues I've found:
Inside the Angular controller, I added the following:
console.log( $(window).scrollTop() );
This snippet logs whatever the scrollTop value was before the page load. It logs this every time, even the times when scrolling works fine.
Even more confusingly, in the HTML itself, I added the following event listener:
$(window).on("scroll", function(e) {
console.log("Scroll event logged. Current scroll position: ", $(window).scrollTop());
})
This consistently logs, on page load, that a scroll event was detected, and that the scrollTop is now 0.
Even more confusingly, sometimes, when the scrolling does work and the additional content is added, it jumps me straight to the bottom, as if I started scrolling from the bottom.
What I think is happening
I think when the page reloads, it retains its now-impossible scrollTop value. Since the scrollTop is below the document height, the browser tries to scroll back up to zero, but this mechanism is buggy and unpredictable.
Does anyone know a surefire way to reset the scroll position to the top of the page, on page load? Simply using $(window).scrollTop(0) isn't working. I'm hoping someone understands the lower levels of this mechanism (or knows another way around it).
I've tried a number of dirty hacks (like scrolling the window by 1px when the additional content gets loaded), and nothing seems to be working. I've been stuck on this for a couple hours now and it's driving me a bit insane.
Also, I'd love to put this in a JSFiddle, but since you can't refresh a JSFiddle page without losing all the code (or having it reset to a non-running state), it wouldn't work. Sorry!
How can I keep the browser from scrolling, or how can I make the browser continually scroll to a fixed posistion?
I am working on a library for the Nintendo 3DS browser. I made the page fit perfectly within the browser, but the up arrow makes it scroll because the bottom screen is the only window recognized as the visible area.
I want to make it so the div #bottomScreen is the only thing in the bottom screen, and disabling scrolling is the only thing I can think that would work.
I have figured out how to scroll it to a said position via
document.body.scrollTop = 220;
How can I make it continually go to this position?
Making a repeating timer with setTimeout and putting the above code in it won't work. I believe it is because this only works prior to the page loading.
Any advice on how to enforce it?
It should work even after page load. Here's the code, although i'm not sure what the intent of the code is, might be annoying to the user.
setInterval( function(){ document.body.scrollTop = 200 }, 500 ); // set your time
A more elegant solution would be to disable scrolling when that method is called (to scroll to the position of 220 from top or whatever), and re-enable it whenever the appropriate action has been taken by the user etc... jQuery example:
$('body').css('overflow', 'hidden'); // removes scrollbars entirely
$('body').css('overflow', 'auto'); // re-enable scrolling
Otherwise use setInterval() with a very short interval like 10ms to repeatedly fire your scroll function. If you are going to do this it would be wise to add some logic to see if the window is already scrolled to approximately the right position (allow for +/- 10px or something) so it isn't extremely jarring for the user.
The best way I've seen on some sites (like twitter I think or facebook when an image pops up) which is to set the overflow property to hidden on the body element. This prevents any scrolling so all you need to worry about is the position of content when you do that.
I guess you would need to wrap the content in some sort of container element and when you change the overflow of the body element you also set the y-coordinate of the container to reveal the specific area of the page being looked at.
This is by far the best thing I have seen to achieve that effect because it doesn't require timers etc.
You could add a event listener for the scroll event, and then set the position then.
I'm looking for some guidance on how I can recreated a this feature. what it does is when you scroll past a certain point something slides in on the right. You can see it action here.
http://mashable.com/2011/08/19/hp-touchpad-lower-prices-canada/#comment-17611181
can anyone help me understand how that happens? The source code tells me nothing..
There probably is a jQuery plugin that does what you need already, but since I don't one, here's the basic procedure:
Set scroll-event listener on the window: $(window).scroll(function(){…});
In that event listener function, check the window.scrollY property which is how many pixels the page is scrolled down
If that value is above/below a certain threshold, show/hide the sliding element respectively
You can also use window.scrollY + window.innerHeight to find lowest pixel position that's visible in the browser. And you can then compare that to the position of some element low on the page. For instance, if you want the sliding element to appear when the user scrolls to the bottom of the main content, check whether the content element's lower edge (i.e. top-offset + height) is less than scrollY+innerHeight. If it is, then the user has scrolled to or past the content element, and you can slide the element in.
The sliding element iself should be styled with position:fixed (which won't work in IE6, by the way, but there are ways around that) and anchored to the rigth/bottom of the window. The sliding animation should then animate the right position from negative the element's width to zero, to slide it in (the opposite applies when hiding it)
Here's a simple demo (no animation, just hide/show)