[javascript] Disable scrolling in an iPhone web application?

Is there any way to completely disable web page scrolling in an iPhone web app? I've tried numerous things posted on google, but none seem to work.

Here's my current header setup:

<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>

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

doesn't seem to work.

This question is related to javascript iphone scroll

The answer is


document.ontouchmove = function(e){ 
    e.preventDefault(); 
}

is actually the best choice i found out it allows you to still be able to tap on input fields as well as drag things using jQuery UI draggable but it stops the page from scrolling.


Disable:

document.ontouchstart = function(e){ e.preventDefault(); }

Enable:

document.ontouchstart = function(e){ return true; }

This should work. No more gray areas at the top or bottom:)

<script type="text/javascript">
   function blockMove() {
      event.preventDefault() ;
}
</script>

<body ontouchmove="blockMove()">

But this also disables any scrollable areas. If you want to keep your scrollable areas and still remove the rubber band effect at the top and bottom, see here: https://github.com/joelambert/ScrollFix.


document.addEventListener('touchstart', function (e) {
    e.preventDefault();
});

Do not use the ontouchmove property to register the event handler as you are running at risk of overwriting an existing event handler(s). Use addEventListener instead (see the note about IE on the MDN page).

Beware that preventing default for the touchstart event on the window or document will disable scrolling of the descending areas.

To prevent the scrolling of the document but leave all the other events intact prevent default for the first touchmove event following touchstart:

var firstMove;

window.addEventListener('touchstart', function (e) {
    firstMove = true;
});

window.addEventListener('touchmove', function (e) {
    if (firstMove) {
        e.preventDefault();

        firstMove = false;
    }
});

The reason this works is that mobile Safari is using the first move to determine if body of the document is being scrolled. I have realised this while devising a more sophisticated solution.

In case this would ever stop working, the more sophisticated solution is to inspect the touchTarget element and its parents and make a map of directions that can be scrolled to. Then use the first touchmove event to detect the scroll direction and see if it is going to scroll the document or the target element (or either of the target element parents):

var touchTarget,
    touchScreenX,
    touchScreenY,
    conditionParentUntilTrue,
    disableScroll,
    scrollMap;

conditionParentUntilTrue = function (element, condition) {
    var outcome;

    if (element === document.body) {
        return false;
    }

    outcome = condition(element);

    if (outcome) {
        return true;
    } else {
        return conditionParentUntilTrue(element.parentNode, condition);
    }
};

window.addEventListener('touchstart', function (e) {
    touchTarget = e.targetTouches[0].target;
    // a boolean map indicating if the element (or either of element parents, excluding the document.body) can be scrolled to the X direction.
    scrollMap = {}

    scrollMap.left = conditionParentUntilTrue(touchTarget, function (element) {
        return element.scrollLeft > 0;
    });

    scrollMap.top = conditionParentUntilTrue(touchTarget, function (element) {
        return element.scrollTop > 0;
    });

    scrollMap.right = conditionParentUntilTrue(touchTarget, function (element) {
        return element.scrollWidth > element.clientWidth &&
               element.scrollWidth - element.clientWidth > element.scrollLeft;
    });

    scrollMap.bottom =conditionParentUntilTrue(touchTarget, function (element) {
        return element.scrollHeight > element.clientHeight &&
               element.scrollHeight - element.clientHeight > element.scrollTop;
    });

    touchScreenX = e.targetTouches[0].screenX;
    touchScreenY = e.targetTouches[0].screenY;
    disableScroll = false;
});

window.addEventListener('touchmove', function (e) {
    var moveScreenX,
        moveScreenY;

    if (disableScroll) {
        e.preventDefault();

        return;
    }

    moveScreenX = e.targetTouches[0].screenX;
    moveScreenY = e.targetTouches[0].screenY;

    if (
        moveScreenX > touchScreenX && scrollMap.left ||
        moveScreenY < touchScreenY && scrollMap.bottom ||
        moveScreenX < touchScreenX && scrollMap.right ||
        moveScreenY > touchScreenY && scrollMap.top
    ) {
        // You are scrolling either the element or its parent.
        // This will not affect document.body scroll.
    } else {
        // This will affect document.body scroll.

        e.preventDefault();

        disableScroll = true;
    }
});

The reason this works is that mobile Safari is using the first touch move to determine if the document body is being scrolled or the element (or either of the target element parents) and sticks to this decision.


I tried above answers and particularly Gajus's but none works. Finally I found the answer below to solve the problem such that only the main body doesn't scroll but other scrolling sections inside my web app all work fine. Simply set position fixed for your body:

body {

height: 100%;
overflow: hidden;
width: 100%;
position: fixed;
}

The page has to be launched from the Home screen for the meta tag to work.


Change to the touchstart event instead of touchmove. Under One Finger Events it says that no events are sent during a pan, so touchmove may be too late.

I added the listener to document, not body.

Example:

document.ontouchstart = function(e){ 
    e.preventDefault(); 
}

If you are using jquery 1.7+, this works well:

$("donotscrollme").on("touchmove", false);

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to iphone

Detect if the device is iPhone X Xcode 8 shows error that provisioning profile doesn't include signing certificate Access files in /var/mobile/Containers/Data/Application without jailbreaking iPhone Certificate has either expired or has been revoked Missing Compliance in Status when I add built for internal testing in Test Flight.How to solve? cordova run with ios error .. Error code 65 for command: xcodebuild with args: "Could not find Developer Disk Image" Reason: no suitable image found iPad Multitasking support requires these orientations How to insert new cell into UITableView in Swift

Examples related to scroll

How to window.scrollTo() with a smooth effect Angular 2 Scroll to bottom (Chat style) Scroll to the top of the page after render in react.js Get div's offsetTop positions in React RecyclerView - How to smooth scroll to top of item on a certain position? Detecting scroll direction How to disable RecyclerView scrolling? How can I scroll a div to be visible in ReactJS? Make a nav bar stick Disable Scrolling on Body