There are a number of ways for a user to scroll a browser window, but there's one I find particularly irksome and would like to suppress. This would be where you click with the mouse and then drag the mouse outside of the window and it scrolls in the direction the mouse has been dragged.
This behavior is particularly annoying because the page I'm working on does things on both mousedown and mousemove, so its fairly easy for the user to be in the middle of this operation and slip off the page and screw up what they were doing. I can't just overflow: hidden because I do want the user to be able to scroll, just not by this particular method.
I could imagine lots of apps where this is a problem; for instance, click and drag away from center to zoom on the current frame of content with existing scrollbars might even want to support the mouse leaving the window via capture-mode events, but this will cause it to scroll!
The only thing I can think to do is do { overflow: hidden } and then implement custom scrollbars, but custom scrollbars tend to suck. I've been searching around for awhile and trying different things, but haven't seen a solution to this. Pardon if it's a dupe and I just didn't find the original.
I found a reasonable answer to your question here: Disabling middle click scrolling with javascript
It seems that it's possible on certain browsers, but you might want to just tell people not to do that. It's not a very common action anyways.
Related
I have a fixed element which covers the entire screen and need scrolling.
IOS has what people call 'rubbing banding' for an example of this behavior you can take a look at these gifs:
http://blog.christoffer.me/six-things-i-learnt-about-ios-safaris-rubber-band-scrolling/
The problem is that when rubber banding occurs and pulls my fixed element down(revealing the content it overlays) there is a chance a users finger might end up on the content which is being overlay-ed.
When this happens all touchmove event will trigger not on my fixed element that covers the screen but on the body that my fixed element is overlaying.
I know you can prevent the body from scrolling in a maner like this:
body.noscroll{
position:fixed;
overflow:hidden;
}
But this is a solution to prevent scrolling.
This is not the solution because once the touchmove event has triggered on the overlay-ed content once, it will only stop if a user removes their finger from the screen.
In short a user might scroll my fixed element, reach the top making the rubber banding kick in and swipe on the body instead of the fixed element because the rubber banding reveals the body.
Even if the element pops back into place after the rubber banding has taken place the touchmove event is still stuck on the body element until the user removes his finger from the screen.
I am pretty lost on what to do here. Somehow disabling the touchmove event for the body seems like a good idea but my fixed element is inside there and it still needs scroll abilities.
Any thoughts or tips on how to handle this?
Edit:
A simply jsfiddle:
https://jsfiddle.net/pq88zLLx/1/
This only works on IOS though and only if you swipe into the content that the rubber banding is revealing.
There really is not a good solution for dealing with a fixed element that has scrolling inside of it on mobile browsers.
I have not tested other browsers besides Safari but I've learned that other browsers are not too fond of this combination either.
The best and most flexible solution is to make your full screen elements absolute positioned. This will fix common issues with swiping and positioning.
But what if my element is in a relative container?
Then you are out of luck and need to grab your element, remove it from the dom and place it up as high in the dom as you can when you are opening your fullscreen element.
Afterwards you need to place your element back in it's original position. They best way I know of to do this, is to leave behind a placeholder for you to append/prepend to. The dom has no method your giving you the exact location of an element therefore if you don't want the order of elements to change you are forced to do this.
Feel free to leave comments or suggestions on this answer if you feel like improvements can be made.
I'm working on horizontal website. I would like to create 2 buttons (left button and right button) which can help users to scroll to left and right.
The site that I'm working on
The functionality that I wanted to create is, when I mouseover the button the page will start and continue the scrolling action until the mouse move away from the button then the page stop scrolling.
I found something from codepen "http://goo.gl/uTQdzD" that is similar to what I looking for but that is not function in the way I wanted. It's required to keep clicking it only it can continue scroll, once it clicked then it only move a certain pixels distances and stop then have to click again... even I tried to change to mouseover, the same thing... I have to moving the mouse in and out the button only it can continue to scroll the page.
I'm not a professional web coder or developer but just a new guy. I Hope someone out here could help me out.
Thanks in advance.
Here you go: http://codepen.io/caseybaggz/pen/uBysA?editors=001
I changed the .click to a mouseenter event which is what you are looking for. Additionally, the increments that you noticed were happening because of the step variable being assigned 400. So, I just replaced the 400 with wWidth and within the mouseenter function, told it to scroll the bodyWidth.
I'm not totally sure why you would want to do this? The natural flow of web design is to design/build sites vertically. To have the user scroll horizontally is a little awkward regarding the UX and could be considered bad design…especially now that devices come into play.
Be sure to learn web-design and UX standards first before you get into a position for developing sites. It not only helps to contribute for bettering the web, but also the UX. ;)
Hope this helps and good luck!
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.
I have seen a feature on a site I would like to emulate. I have intermediate php skill but am a novice javascript user. The feature is the site content displayed in divs which can be moved around on the screen and their position saved using cookies. This site: [url]www.nowgamer.com[/url] is where I saw it (latest podcasts, videos, reviews etc with filter)
How would I go about achieving this through javscript? I want to know how to connect javascript with the cookie so that the positions of the square divs are saved, as are the preferences of the content filter on each div. How can I achieve this?
Would this be a big job? Thank you for any help, I am working independently on this in my spare time so your contribution with advice is my lifeline.
As Zoidberg commented, its easy with JQuery or Yui, or any other javascript library that provides drag & drop functionality. They are almost easy to configure, checking at demo they give. They also expose certain events like beforeDrag, afterDrag, onDrop, etc. where you can fire a simple js function check the elements' dropped position store it in cookies. For setting cookies, there are world of code on internet.
Also, you might want to check floating absolute/relative positioning css, if your DOM divs are going to be floating around the page.
GoodLuck.
simplyharsh has the proper answer, but I'd like to expand on it a bit:
The basics of a draggable div aren't too complicated. You attach an onclick handler to initiate the dragging. Internally, that's accomplished by changing the div's CSS so it's position: absolute. Then you start monitoring mouse movements (basically onmousemove) and changing the div's top and left according to the movements you've captured.
Dropping is a bit more complicated. You can always just release the mouse and leave the div wherever you ended up moving it, but that leaves it absolutely positioned and therefore outside of normal document flow. But dropping it "inside" some other element means a lot of prep work.
Because of how mouseover/mouseout/mouseenter events work, they WON'T work while you're dragging an element - you've got your draggable div under the mouse at all times, so there's no mouseenter/leave events being fired on the rest of the page. jquery/mootools and the like work around it letting you specify drop zones. The locations/sizes of these zones are precalculated and as you're dragging. Then, as you're dragging, the dragged object's position is compared to these precalculated drop zone locations for every move event. If you "enter" one of those zones, then internally the libraries fire their mouseenter/mouseleave/mouseover events to simulate an actual mouseenter/leave/over event having occured.
If you drop inside a zone, the div gets attached as a child of that zone. If you drop outside, then it will usually "snap back" to where it was when you initiated the drag.
Resizing is somewhat similar, except you're adjusting height and width instead of top and left.
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!