9

I have an IOS Web App that can't be scrolled. For that reason I want to deactivate scrolling. To do this, I use an element's ontouchmove attribute and have it call a function that uses element.preventDefault. However, I am unable to detect any touching event when it starts on a textarea or input element, even when the element is disabled! I have also tried binding the touchmove or touchstart event to these elements via JavaScript's addEventlistener, without success!

And here's my JavaScript:

function onBodyLoad() {

 document.addEventListener( "touchstart", doNotScroll, true );
 document.addEventListener( "touchmove", doNotScroll, true );

}

function doNotScroll( event ) {

 event.preventDefault();
 event.stopPropagation();

}

Thanks for any help!

Louis B.
  • 2,348
  • 1
  • 29
  • 51
  • I came up with a partial solution: http://mobweb.ch/2010-12-06-iosphonegap-prevent-scrolling-when-gesture-starts-on-input-element - Still looking for something better tho! – Louis B. Dec 06 '10 at 15:41

2 Answers2

11

I think I've found a great workaround for this issue using the "pointer-events" CSS property:

function setTextareaPointerEvents(value) {
    var nodes = document.getElementsByTagName('textarea');
    for(var i = 0; i < nodes.length; i++) {
        nodes[i].style.pointerEvents = value;
    }
}

document.addEventListener('DOMContentLoaded', function() {
    setTextareaPointerEvents('none');
});

document.addEventListener('touchstart', function() {
    setTextareaPointerEvents('auto');
});

document.addEventListener('touchmove', function(e) {
    e.preventDefault();
    setTextareaPointerEvents('none');
});

document.addEventListener('touchend', function() {
    setTimeout(function() {
        setTextareaPointerEvents('none');
    }, 0);
});

This will make Mobile Safari on iOS (others not tested so far) ignore the textareas for scrolling but allows to set focus etc. as usual.

Thomas Bachem
  • 1,545
  • 1
  • 16
  • 10
  • My hero! Works on Safari and Chrome for iPad. – nothingisnecessary Mar 29 '16 at 18:55
  • 1
    Is this still a valid solution? I used Dotgreg's jQuery implementation and while it allows you to scroll, you cannot focus the inputs. Bear in mind the form in question is in a Fancybox v2 lightbox, just to add to the misery. Tested this on a 6 Plus running iOS 10 and on BrowserStack on a 7 with iOS10. – Bobe May 05 '17 at 05:09
  • This solution works only in the sense that it allows you to tap an input and scroll, however it makes it impossible to focus the input, which sort of defeats the purpose. The correct solution to preserve expected behavior (i.e. ability to start a scroll even on an input element and still focus the input element) is to add `-webkit-overflow-scrolling: touch;` to your `html` or `body` tag. [See here for more](https://stackoverflow.com/questions/25596960/issues-with-touch-scroll-on-ios-when-focusing-inputs) – Daniel Bonnell Jun 15 '18 at 19:44
2

the Thomas Bachem answer is the one!

I rewrote it in jQuery. Just add a class scrollFix to your desired inputs and you are ready to go. Or attach the event handlers to all inputs and textareas using $('input, textarea').

Now when you touch and scroll on an input on iOS 8+, the input get all its pointer-events disabled (including the problematic behavior). Those pointer-events are enabled when we detect a simple touch.

$('.scrollFix').css("pointer-events","none");

$('body').on('touchstart', function(e) {
    $('.scrollFix').css("pointer-events","auto");
});
$('body').on('touchmove', function(e) {
    $('.scrollFix').css("pointer-events","none");
});
$('body').on('touchend', function(e) {
    setTimeout(function() {
        $('.scrollFix').css("pointer-events", "none");
    },0);
});
Community
  • 1
  • 1
Dotgreg
  • 333
  • 3
  • 9