How can I temporarily prevent a scrollable div from scrolling? - javascript

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!

Related

Trigger function when element is visible, after scrolling down

I want to have a menu bar, which is shrinking its size via function.
My goal is to trigger the function, when the user has scrolled down, so that a specific element (maybe an invisible div) is theoretical visible.
Im specifically asking for a solution with basic JavaScript, without using jquery (because i dont understand it yet)
Thanks

JavaScript/Vue.js: How to execute multiple methods at once before the DOM updates

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!

Prevent Body Element From Scrolling On Touch Devices

The Problem:
I have a web application on the iOS homescreen so there is no browser window and it looks and functions very well. I've figured out how to make inner div elements do the touch scrolling events and use the momentum/bounce style in iOS, and that works perfectly... the issue I run into now is that the bounce scrolling (again, iOS-only) is messing up any fixed elements or site-related animations I have on the page.
When I try the following:
document.ontouchmove = function(e) {e.preventDefault()};
The issue stops, but now I can't scroll anywhere on my application.
What I Need:
I want the body to be completely locked in place... If someone grabs, say, my sidebar or navbar and then pulls on the page, the body bounces! But if someone is inside the content area, there is no issue at all--the application scrolls flawlessly and looks great. If I stop scrolling on the sidebar or navbar or body, all scrolling in the application will not working and is essentially nonfunctional.
tl;dr: Body bounces on scroll. I want a scrolling content area and no scroll anywhere else. The body should NEVER move, but elements I deem scrollable within the body should.
As a sidenote, I've browser the following popular questions/solutions posted (among many others):
1
2
3
I just wanted to post that up before people assumed I didn't do any searching... I've been at this for hours now and have seen even more solutions than posted above, but I wanted to get the most popular ones listed above so no one thought this was a duplicate question.
I figured this out a few days ago and have this handy jsbin set up to demonstrate what I did to make this work:
My Working jsbin Example
When you open this link on an iPad, the text should be scrollable. Try tugging around the rest of the screen when there is no current touchmove event currently working.
If you play around with it, you'll notice that only the inner textfield moves as expected. This is determined by putting my .scrollable class within the .container class. The .scrollable class takes up the full height of it's parent container.
Now make the container a larger height, like height: 500px. The goal here is to make it large enough to have no overflow yet small enough to have other whitespace on the iPad still. Try scrolling it or pulling it... No touchmove events are fired and the screen stays in place.
My JS determines if an object has overflow after being touched. If it does, it scrolls. If it does not, it does not send a scroll event.
Play with it and let me know if I can provide any better examples and also if you run into any bugs... Right now the only one I know of is if you're really trying to break it and start tugging around the site while a current touchmove event is being fired, or the page is first loading... I wouldn't count those as "bugs", but if you can find a fix for those too, I'm all ears!

Hiding and showing div during page scroll on iphone

Need to display an element (div) ontop of webpage. During scroll the element should disappear and reappear after scroll ends.
To add to the complexity:
our code is a guest code (thus we cannot manipulate DOM structure etc).
our code is intended to work on iPhone/iPad (mobile Safari browser)
We've tried to listen to touchstart event on document / body and hide the element (div) in our dedicated handler. However, in some sites, (when DOM structure becomes reasonably complex) the scroll response time increases significantly, even if handler implementation is entirely empty.
We are looking for the proper way to manage the element (re)appearance with a minimal affect of the user experience while scrolling.
I would think Javascript is your best solution. You can dynamically insert your DIV to any content using document.createElement, then also add some javascript to listen for onScroll...
You could even populate the DIV using custom HTML built from the native code if you want.
Any help?
I don't know if you are a jQuery user, but this .scroll() function may help you do exactly what you want to do. Check out the demo to see how it works.
http://api.jquery.com/scroll/
In recent iOS version (5.x) fixed positioning (position:fixed in CSS) is fluently supported, so that your element will be positioned on screen coordinates. That might be a good starting point for solving your troubles.

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.

Categories