-webkit-overflow-scroll:touch;
将样式设置为textarea元素的样式,就可以使用一个手指轻松地滚动。
但是有一个问题。为了防止整个屏幕滚动,建议Web应用程序添加以下代码:
document.ontouchmove = function(e) {e.preventDefault()};
然而,这将禁用新的滚动条。
有没有一种好的方法可以允许在文本区域内使用新的滚动条,但不允许整个表单滚动?
-webkit-overflow-scroll:touch;
将样式设置为textarea元素的样式,就可以使用一个手指轻松地滚动。
但是有一个问题。为了防止整个屏幕滚动,建议Web应用程序添加以下代码:
document.ontouchmove = function(e) {e.preventDefault()};
然而,这将禁用新的滚动条。
有没有一种好的方法可以允许在文本区域内使用新的滚动条,但不允许整个表单滚动?
更新 根据Alvaro的评论,这种解决方案可能无法在iOS 11.3及之后的版本中正常工作。
你可以通过选择是否调用preventDefault来允许滚动。例如:
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();
};
编辑 对于后来的读者,备选答案确实可行且更加简单。
e.target
而不是 e.currentTarget
,因为 e.currentTarget
总是指向监听器所附加的元素, 在这种情况下是 document
。 - Derek HendersonBrian Nickel的回答唯一的问题是(如user1012566所提到的),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();
});
event.pageY
替换为 event.targetTouches[0].pageY
。 - ehynds如果有人想在 PhoneGap 上实现这个功能,可以在 cordova.plist
中禁用弹性滚动,在 UIWebViewBounce
的值设为 NO
。我希望这能帮助那些像我一样花了很长时间来解决这个问题的人。
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);
};