Android 4.0 browser overflow: scroll and touch/click events - javascript

I've run into a really annoying problem with the stock Android 4.0 browser. I have a div with overflow: scroll, and elements within which scroll horizontally if they exceed the length of the div. The scrolling works fine, but for some reason (only in the Android browser), click/touch events attached to the elements within the div do not get triggered at all, unless you hold your finger on the element and let go EXACTLY at the point in which the highlighting disappears. Just wondering if anybody has encountered this problem and/or has any idea of how to fix it. Thanks.

So the bug seems to only occur when the element bound to a click/tap event within the scrolling container is an anchor (even without href attribute). If it's any other type of element, it works fine.

Related

Click event not fired in floating button if over an element scrolling

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.

IOS Prevent touchmove event being catched by the body behind fixed element

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.

IE11 CSS Translate3d shifts DOM element event

This issue only occurs in IE11 on Hybrid devices like Surface Pro 3!
I have a function that creates an Open and Close menu, which moves a DIV to the right and/or left.
The DIV contains elements with binded events, but when the elements move there is almost a shadow element of the previous position that remains active with the binded events attached to it?
If I click on that shadow then IE repositions the events on the right elements, as illustrated in the below picture.
Any ideas?
The problem was due to using animation, CSS translate3d.
I've changed it to translate and it works fine now.

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.

Categories