I have written a scroller function which will scroll one div inside another one. The idea is to use the setInterval method to change the margin of the inner element to simulate a scrolling div.
The problem I am facing is that the scrolling is not entirely smooth. Sometimes it stops for a split-second and then it resumes. What can I do to remove these random hiccups? (I am moving 1px per 20 milliseconds)
three comments that might make an answer:
i see you are already using jQuery. it has scroll functions that have been smooth for me.
have you tried fractional positions? as in scrollerMarginTop -= 0.7;
also, you should probably clearInterval() unless the user can move the div and you want it to resume scrolling back into place.
if it works great until you interact with it, consider clearing the interval and waiting until interaction occurs and re-intervaling.
hth
It was quite some time ago that you asked this question, but if you haven't found a working solution you could try Smooth Div Scroll which is a jQuery plugin that does exactly what you describe: scroll one div inside another one.
Related
Does scrollIntoView() work in all browsers? If not is there a jQuery alternative?
It is supported yes, but user experience is... bad.
As #9bits pointed out, this has long been supported by all major browsers. Not to worry about that. The main problem is the way that it works. It simply jumps to a particular element that may as well be at the end of the page. By jumping to it, users have no idea whether:
page has been scrolled up
page has been scrolled down
they've been redirected elsewhere
The first two can be determined by scroll position, but who says users kept track of scroll position before jump was done? So it's an nondeterministic action.
The last one may be true especially if the page has moving header that gets scrolled out of view and remaining page design doesn't imply anything on being on the same page (if it also doesn't have any total height vertical element like left menu bar). You'd be surprised how many pages have this problem. just check them out yourself. Go to some page, look at it at top, then press End key and look at it again. It is likely that you'll think it's a different page.
Animated scrollintoview jQuery plugin to the rescue
That's why there still are plugins that perform scroll into view instead of using native DOM function. They usually animate scrolling which eliminates all 3 issues outlined above. Users can easily keep track of the movement.
Looks like it does: http://www.quirksmode.org/dom/w3c_cssom.html
I use Matteo Spinnelli's iScroll-4 and it works in iOS safari as well. It has three methods scrollTo, scrollToElement and scrollToPage. Let's say you have an unordered list of elements wrapped inside a div. As Robert Koritnik has written above, you need to have that slight animation to show that you have scrolled. The below method achieves that effect.
scrollToElement(element, time);
read please about scrollIntoViewIfNeeded
if(el.scrollIntoViewIfNeeded){
el.scrollIntoViewIfNeeded()
}else{
el.scrollIntoView()
}
You can use jQuery alternative and animate <html> and <body> elements:
$('html, body').animate({
scrollTop: $("#myElem").offset().top
}, 1000);
Have not tried this, but seems like piggybacking on built in scrollIntoView function would save much code. Here is what I would do if you want animated action:
Cache current scroll position of the container as START POSITION
run built in scrollIntoView
Cache the scroll position again as the END POSITION
Return container back to START POSITION
Animate scrolling to END POSITION
Css solved it guys!!
I picked the target id with #idSelected and styled it with css "scroll-margin-top" and defined my margin top in rems (use what ever measurement that suits you).
#idSelected {
scroll-margin-top: 10rem;
}
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 know this has probably been asked before but I couldn't find the right answer.
I'm trying to have a link, when you click it, scrolls the page to an element with an ID, with just javascript, and I get to control the speed.
I know about:
document.getElementById('youridhere').scrollIntoView();
and that didn't work. It just snapped into view. I also tried scrollBy but that didn't work since it works in increments. I can write it up to check the remaining distance to the element and if it's less than the increment, then only move what's left, but that seems way too bulky.
I tried scrollTo as well but that wasn't helping much either.
Is there a cleaner way of doing this?
This needs to be javascript only. Here is a jquery equivalent:
var top = target.offset().top;
$('html,body').animate({scrollTop: top}, 1000);
There is no built-in way to smooth scroll. I would use setInterval and scrollBy an increment on each iteration, then clearInterval when done.
You could also check the jQuery source to see how they do it.
Last night I was wondering how it is possible to delay a fadeIn or something similar. It's not something I'm working on, I was just wondering.
If you have a list, with links that activates a tooltip on hover, for example. How do you make it "wait" until you have hovered for 1 second?
I want to do this, so the tool tips doesn't "flicker" when you hover along the list. If you understand what I mean.
The same thing could be used at logins. If you see http://twitter.com/ (not logged in). If the login box in the top, was activated with hover, and not click, it would disappear again if your cursor left the login box. Is it possible to set a "delay" so your cursor could leave the login box, and come back, without it disappearing...?
In short:
- How do you activate a script, when hover after x seconds?
- How do you set a delay for hiding a div (when not hovering) that was activated by hover?
- Is it the same thing, just in reverse?
There is a quite advanced hover plugin that waits for your mouse to slow down before triggering arbitrary code - http://cherne.net/brian/resources/jquery.hoverIntent.html
Alternatively, if you don't need something so advanced... you can simply trigger the animation in a setTimeout(), and on mouseleave call clearTimeout()
Yet another alternative, is to not bother with the delay. If you do a .stop().fadeIn() and a .stop().fadeOut() rather than a simple show() and hide(), you won't get a "flicker" and the effect will look quite nice.
(You can look at .delay() for delaying animation-related code - although this will only delay the animation, even if you move off the div before the delay finishes.)
I'm working on a site for myself, and I'm using a custom horizontal scroller done with Mootools that I got from another site (and got their permission to use). While I've managed to get the scroller to function the way I want to, there are two issues I'm looking to fixed and don't have the know-how myself to figure out.
I've set up a simple demo page here.
You can scroll with your mousewheel/trackpad up and down or left and right, you can grab the scroller and drag it, and you can click anywhere along the line to jump directly. So all the functionality is okay. My issues are:
If you scroll to the middle (or anywhere except the start position), then resize your browser window, the scroller handle will jump back to the start/left even though the contents stays put. If you then start scrolling again the contents will jump back to align with the scroller handle's position. Ideally the handle would stay put when the window is resized, but I can't figure out how to do this on my own.
At the end/right of the page I'd like to have a back button that smoothly scrolls you back to the start/"top". The best I've managed is what you see there now, where the contents scrolls back smoothly, while the scroller simply jumps back to it's first position. While I could work around that by simply have it jump straight back to the start, it would certainly look much nicer if the scroller would smoothly scroll its way back like the contents does.
Any help with this would be greatly appreciated!
Your first issue is occurring because positionIt() is being called every time the window resizes. Looking into that function, you can see that the bottomSlider is being initialized every time. I would break positionIt() into a initializing function and positioning function, and ensure that only the positioning function is called when the window resizes.
The second issue could probably be fixed by creating a separate step() function for the bottomSlider and calling that within onChange, rather than using an inline anonymous function. You could then create a timer or tween that calls step() to move the scrollbar back to its original position (and subsequently move the viewport in accordance with it.)
Hopefully that makes some sense!