javascriptioscssdom-eventstouchmove

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.


Solution

  • 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.