When having a button (or any other element, positioned absolute or fixed) on top of an element with a scrolling area which is actively scrolling (i.e. for example it's decelerating) it seems that the button doesn't receive the click event when clicked.
It seems that when clicking (or touching) the scrollable element area, the scrolling is interrupted, but the button on top of it doesn't receive any event.
I've debugged events for the floating element in Chrome and the only thing received is a mousewheel event.
This is particularly annoying if the button is a navigation button, as you have to click twice to exit the page if the content is decelerating (as opposed to once when the content is still).
I browsed many times for a solution but never found a clue about this behaviour and how to avoid it, so any thoughts will be appreciated.
Sample code here: https://codepen.io/djibarian/pen/bGLoYxY
If you scroll the red box and while still scrolling due to inertia try to click the button, you only manage to stop the scrolling in the box, but the button doesn't receive the click event.
I haven't seen your code, but it's worth checking following.
Check if any element overlaps the positioned fixed element.
Make sure the stacking context of the element is correct.
Try adding a higher z-index and see if it's working. If it works then it's worth changing the dom element order for precedence.
Related
I have a main content in front, a menu absolutely positioned in back and a toggle button which slides the menu in/out (using CSS transformation on main content).
The problem happens on older (2.x) Android browsers (and sometimes somewhere else). When I click the toggle button to close the menu, the click event is "captured" for a while and than it is repeated on the same position as if no transformation were applied on the content. This leads to activating the link in the content, which is undesired.
Demo is here. Use older Android default browser to see the problem. When you open the menu (the icon in the upper left corner) and then close it by clicking the same icon, the page reloads (as if you clicked the link in upper right corner).
I figured, that my events were bind badly. In case of anyone would have the same problem in future, be careful when binding both: touch events and click events. Touch event was fired first in my case, then the transformation happened followed by the click, which led to "duplicating" the event.
I hope the title is accurate enough to portray the problem that I'm facing.
I have a div (tried multiple different things: a, span, button, all face the same problem) that when it is clicked the onclick event will not fire, even though the css div:active will be called.
This appears to be due to the fact that in the div:active I set top: 6px to make a "push down" sort of effect. The effect looks nice, it's just that sometimes, if you click towards the top of the element, or in the center for some reason, the div will appear to "move out" of the way and not call the onclick event.
I thought that a good solution would be to wrap the element in another div then, and attach the onclick event to that div. To my surprise though, the clicks didn't fire towards the top or the middle of the button still.
If I remove top: 6px at the bottom of the div:active, the button works fine, it just doesn't have the same "pushed in" effect.
I'm finding it kind of difficult to explain, so here's a screenshot (the blue areas are where the onclick won't fire):
and here's the code for the initial attempt: http://jsfiddle.net/RS5Q5/6/
and the code for moving the onclick listener outside: http://jsfiddle.net/RS5Q5/4/ (onclick will fire everywhere in the div except the blue parts on the picture)
It's also worth noting that the middle and bottom blue areas appear to click fine in firefox, but not chrome or safari. The top blue area is still a problem.
Any fix or explanation to this strange behavior? Any guidance at all would be appreciated. Thank you.
Might be because the browser gets confused when content moves during a click event. This usually happens because the user presses the mouse button then drags before releasing, but I suppose the same would be true if the content itself moved under the click location.
What happens if you use the mousedown/mouseup events instead of click?
I have an info overlay that works great in Chrome and FF. It is a div containing a table (for border image layout) and then a central content div. I trigger mousedown on the appropriate border table cells.
Once this happens, a different div is brought to the front with z-index, and that passes along the mousemove and mouseup events to handle dragging the info bubble around. Once the mouseup is fired, the info bubble puts the "event" div back to where it was.
I also follow the same process for dragging the lower right corner of the bubble to resize it. Again, works in Chrome and FF, but fails in IE.
IE seems to be restricting the event triggers to the info div. If the mouse manages to move outside the div (from dragging faster then the events fire/update), the info overlay no longer receives mousemove events. However, if I move the mouse back over the overlay (without releasing the button) it continues to receive mouse events.
Edit: In creating some example code (the current functionality is split across several JS modules), it worked in IE. As soon as I find the difference between my example code and the actual code, I will update again.
Edit/Answer: (SO wont let a new user answer their own question in this time span...)
Still not sure what the actual problem was. (If you ask me, a div with a z-index of 100 should be receiving mouse events just fine?)
My solution was to fix my mouse event handling such that I could attach my mousemove and mouseup to the parent div (as should have been done in the first place) for all dragging/resizing behaviors I wanted to set up.
The problem was due to a newbie approach to the events and having stopPropagation() in too many locations preventing me from taking such an approach. (I wanted text, etc in my info box to be selectable).
I adjusted the code so that my text containers only had to stop propagation on mousedown instead of all the mouse events.
I have a web page with left and right DIVs, both set to overflow: auto with content such that both divs have vertical scroll bars.
I use a jquery keyboard event handler attached to document to have SPACE keys and move the selection from one item in the right DIV to the next item in the right DIV. I have a table of options on in the left DIV. If I click on a link on the left, then hit space, the keyboard handler performs the correct operation in the right DIV, but the left DIV also scrolls down. If I click on some blank space in the right DIV and hit space again, everything behaves correctly.
It is clear to me that overflowing DIVs (and presumably other block elements) have focus, but I can't find any discussion on how to manipulate this, nor can I find any information on blocking key events to default handlers. I know there must be a way because Google Reader doesn't have the same problem, but so far I haven't been able to figure out what they are doing to get the behavior I desire.
event.preventDefault(); should do it (add it first in your handler function).
http://api.jquery.com/event.preventDefault/
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!