How to make the browser stay scrolled at a fixed posistion? - javascript

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.

Related

Does scrollIntoView work in all browsers?

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;
}

Smooth vertical scrolling - Block user-scrolling

I've made a page with smooth vertical scrolling, and I was wondering if you can somehow "block" so the user can't use his mouse or touchpad to scroll on the page - when they do that the whole idea kinda stops.
you can see the scrolling on my webpage.
enter link description here
So far I've just hidden the scrollbar so they can't do it.
I guess you can say what I'm asking for is, can you "block" manually scrolling?
Thanks.
they are several solutions, but there's none that I found perfect. The simpliest is:
set the css property "overflow" to hidden (if on your body, you must set height and width to 100% on body and html, plus no margins/padding borders).
also you can add a listenner to scroll events, then prevent them with event.prevendDefault().
But they are always undesirable effects that can "scroll" pages(and blocks) without a mousescroll:
first is selection: your layout break here. To try it, select from the upper and go down, then the page will scroll(with chrome). this is unlikely to happen when there is no text and no drag and drops, but once it happens your users are lost since there is no scrollbars.
second is scrollIntoView(). You can call that via javascript, or the browser will do it automatically sometimes ( href to an anchor, input focus, "scroll memory at reload" ). This is were there is most risks, but there is very few control over these.
finally, one "bad" solution I found is to regularly force scrollTop property of elements to 0. But most probably you won't have to get there and the CSS body { overflow: hidden; height: 100% } will be sufficient.
The way you've done it is fine. I don't think you can cancel a scroll event, like you can with other event (keypress, button clicks etc..)
Setting overflow to hidden would be how I'd do it as well, as that completely stops all scrolling. The event doesn't even take place in the background.
The following code will block scrolling with the mousewheel. While this isn't relevant for me as I can't use the mousewheel to scroll anyway, it may block scrolling with your touchpad.
Just add this to one of your included js files...
window.onmousewheel = document.onmousewheel = function(event){
if (event.preventDefault) event.preventDefault();
event.returnValue = false;
}
Here's an example...
http://jsfiddle.net/johncmolyneux/aSw2g/

Javascript: don't stop scrolling window if the cursor passes over a scrollable div

I'm building a web app that has a grid of many small scrollable divs (actually, Ace editors), and this grid has enough elements that it is larger than the window. When a user begins scrolling over empty space, I want them to be scrolling the window itself; when a user begins scrolling inside a grid element, I want them to scroll the div contents there. The thing is, if a user begins scrolling over empty space, and then scrolls such that their mouse goes over a grid element, that scrollable div captures all the scrolling events, interrupting the user's flow over the grid and "trapping" them inside the grid element.
I can't manually capture onmousewheel events, since AFAIK there's no way to capture horizontal mouse wheel movement separately from vertical, and I want users on Mac OS X to be able to scroll in all directions. I've thought about using JS to add an invisible div with a very high z-index on the first onscroll event, and removing it as soon as onscroll events aren't triggered for a certain period of time. Haven't yet coded this up, but I'm wondering if there's a better solution, or if there are any potential pitfalls that I haven't thought of. Any help or advice would be great! Thanks!
I think a solution for this would be incredibly difficult due to browser support, and the actual solution, which would probably be something like calculating the scroll, backtracking the div, and applying the scroll to the page.
You could do something like this:
$('div').scroll(function(e){
// figure out how much it has scrolled
window.scrollBy(0,howmuch);
});
I don't recommend this solution in the slightest though, I think the better option would be to set the divs to overflow:hidden; and pick up a solid scroll plugin, and use that to customize the scroll behavior on the divs.

Horizontal scroller with Mootools

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!

How can I temporarily prevent a scrollable div from scrolling?

Here is my current situation:
I have a web page containing a couple scrollable divs. Each of those divs contains a number of objects. I am using YUI to display popup menus of actions that can be performed on each object. Each object has its own menu associated with it that is constructed and displayed dynamically. The popup menus can be large and can overlap the bounds of the scrollable div.
From what I believe are issues with focus (the menus must be accessible), when I hover the mouse over an action that lies on top of an edge of the scrollable div, the div automatically scrolls, moving the content but leaving the menu stationary. Trying to move the menu dynamically when this happens is not something I want to do as I believe it would provide a poor user experience.
So I need to prevent this focused menu from scrolling the div. My idea for providing the best user interface is to prevent these inner divs from scrolling when a menu is open. This leaves the menu positioned in the optimal location to show the user which item is being acted upon. If the user wants to scroll the box, they can click to close the menu and then scroll normally.
How can I do this? I need a solution that works across the major browsers.
My first thought was to listen to the onscroll event for that particular element. Unfortunately, there does not seem to be an easy way from there to just prevent the scrolling from happening. For one, my JavaScript event code appears to execute after the actual scrolling has occurred.
Then, I thought that since my code is being run after the object has scrolled, I could just reset obj.scrollTop and obj.scrollLeft. Sure enough, this appears to work, though I am worried that on slow browsers the user will see the content inside the div "jump around". Also, it would be really nice if the amount the element scrolls is part of the event object. Is it stuck in there somewhere? I'm looking for an alternative to having to store the scrollTop and scrollLeft variables for this element and then using them while the scrolling is temporarily disabled.
What is the best way to solve this entire problem?
I agree with Anthony regarding the presentation of the functionality you're trying to disallow. If you're going to disable scrolling, then you should make that part of the page visually disabled or removed.
To that end, you can position a semi-transparent div on top of the scrollable div in question, which would capture the mouse events and visually show that the scrollable div is inactive for now. It would be hard to make cross-browser compatible and wouldn't be perfect, but then again very few client-side tricks like this are.
The simple answer is no you can't do this. Its doubly no if you want a cross-browser solution.
Providing the user with the clear affordance that something can be scrolled then denying them that is just plain poor UI design.
Ok so after your edit it turns out you are not actually trying to prevent the user from scrolling.
The main answer remains true though. It sounds as though the focus is going to rectangle (probably an anchor?) that is not fully in view and causes a scroll. Is there a reason this rectangle must get the focus? For accessibility?
What if you didn't have overflow: scroll and instead you used overflow: hidden and provided scroll up/down buttons that allowed the user to scroll when necessary? These buttons could of course be disabled easily.
Though it may not be the answer you are looking for, if you are to set the display value of the div to 'none' while the page loads (from the server) and then have an event wired to the page load (either pageLoad in ajax.net or attach it to the onload event via javascript) that will make the div display set to 'block' .. that would ensure that slower browsers wouldn't see the div 'jumping around' (could even put a 'loading' image in the div to show users it's doing something and not just invisible)
sorry i couldn't provide a more complex/fluent solution.
I found a way to work around this issue. By removing the menu element from the scrollable div and then appending it directly to document.body, the browsers all stop trying to scroll the div to reveal the focused element (even though the element is already completely visible).
Thanks to all for your time and your answers!

Categories