Отключить прокрутку в веб-приложении iPhone? - PullRequest
57 голосов
/ 23 мая 2010

Есть ли способ полностью отключить прокрутку веб-страницы в веб-приложении iPhone? Я пробовал множество вещей, опубликованных в Google, но ни одна из них, похоже, не работает.

Вот мои текущие настройки заголовка:

<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(); });

не похоже на работу.

Ответы [ 9 ]

56 голосов
/ 23 мая 2010

Изменить на touchstart событие вместо touchmove. В разделе События с одним пальцем говорится, что во время панорамирования события не отправляются, поэтому touchmove может быть слишком поздно.

Я добавил слушателя в документ, а не в тело.

Пример:

document.ontouchstart = function(e){ 
    e.preventDefault(); 
}
16 голосов
/ 11 ноября 2014
document.addEventListener('touchstart', function (e) {
    e.preventDefault();
});

Не используйте свойство ontouchmove для регистрации обработчика событий, так как вы рискуете перезаписать существующие обработчики событий. Вместо этого используйте addEventListener (см. Примечание об IE на странице MDN).

Помните, что предотвращение по умолчанию для события touchstart на window или document отключит прокрутку нисходящих областей.

Чтобы предотвратить прокрутку документа, но оставить все остальные события без изменений, по умолчанию использовать первое touchmove событие, следующее за touchstart:

var firstMove;

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

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

        firstMove = false;
    }
});

Причина, по которой это работает, заключается в том, что мобильный Safari использует первый шаг, чтобы определить, прокручивается ли тело документа. Я понял это, разрабатывая более сложное решение.

В случае, если это когда-нибудь перестанет работать, более сложным решением является проверка элемента touchTarget и его родителей и составление карты направлений, по которой можно прокрутить. Затем используйте первое событие touchmove, чтобы определить направление прокрутки и посмотреть, будет ли оно прокручивать документ или целевой элемент (или любой из родительских элементов целевого элемента):

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;
    }
});

Причина, по которой это работает, заключается в том, что мобильный Safari использует первое касание, чтобы определить, выполняется ли прокрутка тела документа или элемента (или любого из родительских элементов целевого элемента), и придерживается этого решения.

13 голосов
/ 01 мая 2012

Если вы используете jquery 1.7+, это хорошо работает:

$("donotscrollme").on("touchmove", false);
12 голосов
/ 18 ноября 2011

Это должно работать. Больше нет серых областей сверху или снизу:)

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

<body ontouchmove="blockMove()">

Но это также отключает прокручиваемые области. Если вы хотите сохранить прокручиваемые области и по-прежнему удалять эффект резиновой ленты сверху и снизу, см. Здесь: https://github.com/joelambert/ScrollFix.

10 голосов
/ 01 июня 2015

'self.webView.scrollView.bounces = NO;'

Просто добавьте эту строку в 'viewDidLoad' файла mainViewController.m вашего приложения. Вы можете открыть его в Xcode и добавить его.

Это должно сделать страницу без резиновых отскоков, по-прежнему включая прокрутку в представлении приложения.

10 голосов
/ 13 июня 2013

Отключить:

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

Включить:

document.ontouchstart = function(e){ return true; }
4 голосов
/ 20 октября 2010

Страница должна быть запущена с главного экрана, чтобы мета-тег работал.

1 голос
/ 30 мая 2013
document.ontouchmove = function(e){ 
    e.preventDefault(); 
}

фактически лучший выбор, который я обнаружил, он позволяет вам по-прежнему иметь возможность нажимать на поля ввода, а также перетаскивать объекты с помощью перетаскиваемого пользовательского интерфейса jQuery, но останавливает прокрутку страницы.

0 голосов
/ 21 сентября 2017

Я пробовал приведенные выше ответы и особенно ответы Гайюса, но ни один из них не работает. Наконец, я нашел ответ ниже, чтобы решить проблему так, что только основная часть не прокручивается, а другие разделы прокрутки внутри моего веб-приложения работают нормально. Просто установите фиксированное положение для вашего тела:

body {

height: 100%;
overflow: hidden;
width: 100%;
position: fixed;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...