Предотвратите отклонение прокрутки для элемента body, но сохраните его для дочерних элементов в iOS

В последнее время я работаю над мобильным webapp. Я оптимизирую первый мобильный телефон, ориентируясь именно на iOS для iPhone прямо сейчас. Мне не нужен точный внешний вид родного приложения, но я считаю, что чувство принадлежности к природе является абсолютным. Я сделал разметку и CSS, чтобы отразить эту идею, оставив меня с этим (аннотированный, чтобы лучше понять проблему, с которой я столкнулся):

Webapp markup

Все это работает без проблем, и у него также есть преимущество иметь собственное ощущение со статическим верхним и нижним колонтитулом и прокручиваемый внутренний вид (благодаря -webkit-overflow-scrolling: touch).

Как любой, кто использовал iOS более 5 минут, будет знать, когда вы прокручиваете вверх или вниз, вы получаете хорошую импульсную прокрутку. Кроме того, когда вы попадаете в верхнюю часть списка, вы получаете хороший эффект "отскока":

List bouncing in Settings.app

Я чувствую, что это помогает определить ощущение iOS, и такая маленькая деталь может пройти долгий путь. К счастью, когда вы находитесь под вершиной списка в прокручиваемом элементе в webapp и прокручиваете верхнюю часть, вы получаете тот же эффект. Это желаемое поведение в действии:

Scrolling down and up in a webapp produces this bouncing effect

Однако, когда вы находитесь в верхней части списка и пытаетесь воссоздать одно и то же поведение отскока вверху списка (à la Setting.app, см. выше), мы получаем следующее поведение, которое Нежелательный: Scrolling down produces the bouncing effect for the entire chrome of the app

Я видел несколько похожих questions в переполнении стека, но все они выбирают отключить подпрыгивая. Мне интересно, возможно ли продолжать прыгать, но всегда делать это на body section section#main, а не на webapp chrome. Я не использую jQuery, поэтому я бы предпочел, чтобы ответы были в прямом JavaScript (бонусные баллы для решения CSS).

Здесь GitHub repo со всем кодом (Sinatra, HAML и Sass, текущая ветвь so) или JSFiddle со сломанными изображениями и ссылками, но показывает проблему, о которой идет речь на iPhone (лучше всего добавить на рабочий стол для проверки).

Ответ 1

OLD INFO: Я решил это: http://www.hakoniemi.net/labs/scrollingOffset/nonbounce.html

NEW INFO: Теперь это плагин jQuery, который можно найти здесь: http://www.hakoniemi.net/labs/nonbounce/.

Существует несколько проблем, например, потеря функции масштабирования при ее применении или динамическое обновление не работает.

Но теперь самым простым способом является определение: <div class="nonbounce">...</div>, а затем $.nonbounce();

Ответ 2

Я столкнулся с той же проблемой и придумал это решение:

http://demo.josefkjaergaard.com/stackoverflow/element_scroll/index.html

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

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

Ответ 3

Как насчет этого псевдокода:

document.body.addEventListener("ontouchstart", function(event) {
  if(document.getElementById("main").scrollTop > 0) return;
  event.preventDefault();
  event.stopPropagation();
}, false);