document.ontouchmove 和在 iOS 5 上滚动

IT技术 javascript scroll ios5
2021-02-17 23:49:00

iOS 5 为 JavaScript/Web 应用程序带来了许多好东西。其中之一是改进滚动。如果添加

-webkit-overflow-scroll:touch;

对于 textarea 元素的样式,用一根手指滚动可以很好地工作。

但是有一个问题。为了防止整个屏幕滚动,建议网络应用添加这行代码:

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

但是,这会禁用新的滚动。

有没有人有一个很好的方法来允许在 textarea 内进行新的滚动,但不允许整个表单滚动?

5个回答

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

编辑对于稍后阅读的任何人,替代答案确实有效并且更容易。

@Alvaro 您找到解决方案了吗?
2021-04-17 23:49:00
我相信您应该使用e.target,而不是e.currentTarget,因为e.currentTarget在这种情况下将始终指代侦听器附加到的元素document
2021-04-21 23:49:00
很棒的一个简单的解决方案。替代jquery插件解决方案hakoniemi.net/labs/nonbounce
2021-05-07 23:49:00
@Kellen 是的,请改用 touchstart,请在此处查看我的问题:stackoverflow.com/questions/49926360/...
2021-05-15 23:49:00

Brian 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();
});
我无法让它在 IOS6 上工作,它实际上阻止了在 PC 浏览器上滚动。在 IOS 上,如果您已经滚动过边界一次,它只会阻止弹性滚动。
2021-04-28 23:49:00
是的,正是他所说的^
2021-05-01 23:49:00
要修复,替换所有出现的event.pageYevent.targetTouches[0].pageY
2021-05-01 23:49:00
这个解决方案似乎不太奏效。当滚动达到其上限或下限时,元素只是冻结在其当前位置,因此我无法向任一方向滚动。我正在使用 iOS 7.1。
2021-05-10 23:49:00

对于任何试图与PhoneGap的,以达致这,你可以在禁用弹性滚动cordova.plist,对于设置的值UIWebViewBounceNO我希望能帮助任何人在这上面花费很多时间(就像我一样)。

谢谢你,安德鲁!我只需要花半年的时间来寻找这个!
2021-04-29 23:49:00
谢谢!省了我一堆追鬼的时间!
2021-05-02 23:49:00
关于此的其他选项/文档:tripleshotsoftware.blogspot.com/2012/09/...
2021-05-05 23:49:00

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

发现 stopPropagation 和本机 div 滚动的已知问题令人沮丧。它似乎并没有阻止 onTouchMove 向上冒泡,因此当滚动超出 div 的边界(顶部向上或底部向下)时,整个页面都会反弹。

更多讨论在这里这里

仅供参考,您可以使用下面列出的解决方案来防止这种情况发生。
2021-04-17 23:49:00