Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent document scrolling but allow scrolling inside div elements on websites for iOS and Android?

I created a website with jQueryMobile for iOS and Android.

I don't want the document itself to scroll. Instead, just an area (a <div> element) should be scrollable (via css property overflow-y:scroll).

So I disabled document scrolling via:

$(document).bind("touchstart", function(e){
    e.preventDefault();
});

$(document).bind("touchmove", function(e){
    e.preventDefault();
});

But that will also disable scrolling for all other elements in the document, no matter if overflow:scroll is set or not.

How can I solve this?

like image 600
Timo Ernst Avatar asked Feb 28 '13 10:02

Timo Ernst


People also ask

How do I turn off scrolling In IOS?

Go to Settings and tap Accessibility. Turn on the feature, then use the slider to select a sensitivity level.

How do you stop background scrolling in CSS?

To hide the scrollbar and disable scrolling, we can use the CSS overflow property. This property determines what to do with content that extends beyond the boundaries of its container. To prevent scrolling with this property, just apply the rule overflow: hidden to the body (for the entire page) or a container element.


3 Answers

How about this CSS only solution:

https://jsfiddle.net/Volker_E/jwGBy/24/

body gets position: fixed; and every other element you wish an overflow: scroll;. Works on mobile Chrome (WebKit)/Firefox 19/Opera 12.

You'll also see my various attempts towards a jQuery solution. But as soon as you're binding touchmove/touchstart to document, it hinders scrolling in the child div no matter if unbinded or not.

Disclaimer: Solutions to this problem are in many ways basically not very nice UX-wise! You'll never know how big the viewport of your visitors exactly is or which font-size they are using (client user-agent style like), therefore it could easily be, that important content is hidden to them in your document.

like image 85
Volker E. Avatar answered Oct 10 '22 19:10

Volker E.


Maybe I misunderstood the question, but if I'm correct:

You want not to be able to scroll except a certain element so you:

$(document).bind("touchmove", function(e){
    e.preventDefault();
});

Prevent everything within the document.


Why don't you just stop the event bubbling on the element where you wish to scroll? (PS: you don't have to prevent touchstart -> if you use touch start for selecting elements instead of clicks that is prevented as well, touch move is only needed because then it is actually tracing the movement)

$('#element').on('touchmove', function (e) {
     e.stopPropagation();
});

Now on the element CSS

#element {
   overflow-y: scroll; // (vertical) 
   overflow-x: hidden; // (horizontal)
}

If you are on a mobile device, you can even go a step further. You can force hardware accelerated scrolling (though not all mobile browsers support this);

Browser Overflow scroll:

Android Browser Yes
Blackberry Browser  Yes
Chrome for Mobile   Yes
Firefox Mobile  Yes
IE Mobile           Yes
Opera Mini          No
Opera Mobile    Kinda
Safari          Yes

#element.nativescroll {
    -webkit-overflow-scrolling: touch;
}

normal:

<div id="element"></div>

native feel:

<div id="element" class="nativescroll"></div>
like image 12
Danillo Felixdaal Avatar answered Oct 10 '22 17:10

Danillo Felixdaal


Finally, I got it to work. Really simple:

var $layer = $("#layer");
$layer.bind('touchstart', function (ev) {
    var $this = $(this);
    var layer = $layer.get(0);

    if ($this.scrollTop() === 0) $this.scrollTop(1);
    var scrollTop = layer.scrollTop;
    var scrollHeight = layer.scrollHeight;
    var offsetHeight = layer.offsetHeight;
    var contentHeight = scrollHeight - offsetHeight;
    if (contentHeight == scrollTop) $this.scrollTop(scrollTop-1);
});
like image 12
Timo Ernst Avatar answered Oct 10 '22 18:10

Timo Ernst