Document.ontouchmove и прокрутка на iOS 5
iOS 5 принес много приятных вещей в JavaScript/Web Apps. Одна из них - улучшенная прокрутка. Если вы добавите
-webkit-overflow-scroll:touch;
в стиле элемента textarea, прокрутка будет работать с одним пальцем.
Но есть проблема. Чтобы предотвратить прокрутку всего экрана, рекомендуется, чтобы веб-приложения добавили эту строку кода:
document.ontouchmove = function(e) {e.preventDefault()};
Это, однако, отключает новую прокрутку.
Есть ли у кого-нибудь хороший способ разрешить новую прокрутку в текстовом поле, но не разрешить прокрутку всей формы?
Ответы
Ответ 1
Обновление Согласно комментарию Alvaro, это решение может больше не работать с iOS 11.3.
Вы должны быть в состоянии разрешить прокрутку, выбрав, вызывать или нет, предотвращение дефолта. Например,
document.ontouchmove = function(e) {
var target = e.currentTarget;
while(target) {
if(checkIfElementShouldScroll(target))
return;
target = target.parentNode;
}
e.preventDefault();
};
В качестве альтернативы это может сработать, если событие не достигнет уровня документа.
elementYouWantToScroll.ontouchmove = function(e) {
e.stopPropagation();
};
Редактировать Для тех, кто читает позже, альтернативный ответ работает и намного проще.
Ответ 2
Единственная проблема с ответом Брайана Никеля заключается в том, что (как указано пользователем1012566) stopPropagation не мешает пузыриться, когда вы нажимаете свои прокручиваемые границы. Вы можете предотвратить это со следующим:
elem.addEventListener('touchstart', function(event){
this.allowUp = (this.scrollTop > 0);
this.allowDown = (this.scrollTop < this.scrollHeight - this.clientHeight);
this.prevTop = null;
this.prevBot = null;
this.lastY = event.pageY;
});
elem.addEventListener('touchmove', function(event){
var up = (event.pageY > this.lastY),
down = !up;
this.lastY = event.pageY;
if ((up && this.allowUp) || (down && this.allowDown))
event.stopPropagation();
else
event.preventDefault();
});
Ответ 3
Для тех, кто пытается добиться этого с помощью PhoneGap, вы можете отключить прокрутку в режиме cordova.plist
, установите для параметра UIWebViewBounce
значение NO
значение UIWebViewBounce
. Надеюсь, что это поможет любому, кто потратил на это время (как и я).
Ответ 4
ScrollFix кажется идеальным решением. Я тестировал его, и он работает как шарм!
https://github.com/joelambert/ScrollFix
/**
* ScrollFix v0.1
* http://www.joelambert.co.uk
*
* Copyright 2011, Joe Lambert.
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*/
var ScrollFix = function(elem) {
// Variables to track inputs
var startY, startTopScroll;
elem = elem || document.querySelector(elem);
// If there is no element, then do nothing
if(!elem)
return;
// Handle the start of interactions
elem.addEventListener('touchstart', function(event){
startY = event.touches[0].pageY;
startTopScroll = elem.scrollTop;
if(startTopScroll <= 0)
elem.scrollTop = 1;
if(startTopScroll + elem.offsetHeight >= elem.scrollHeight)
elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1;
}, false);
};
Ответ 5
Было неприятно обнаружить известную проблему с stopPropagation и прокруткой родной div. Кажется, что это не мешает потоку onTouchMove, так что при прокрутке за пределы div (вверху вверху или внизу внизу) вся страница будет отскакивать.
Подробнее обсуждение здесь и здесь.