触摸移动某些元素时禁用滚动

IT技术 javascript jquery-mobile touch
2021-02-24 01:33:40

我有一个页面,其中有一个部分可以在其中绘制绘图。但是在移动浏览器上使用它时,touchmove 事件(至少是垂直事件)也会滚动页面(这会降低草绘体验)。有没有办法a)禁用并重新启用页面滚动(这样我可以在每行开始时将其关闭,但在每行完成后重新打开),或b)禁用默认处理进入绘制草图的画布的 touchmove 事件(可能还有滚动)(我不能完全禁用它们,因为草图使用它们)?

我已经为草图使用了 jquery-mobile vmouse 处理程序,如果这有区别的话。

更新:在 iPhone 上,如果我选择要在其中绘制草图的画布,或者在绘图前仅按住手指一点,页面不会滚动,这不是因为我在页面中编码的任何内容。

6个回答

touch-action CSS 属性设置为none,即使与被动事件侦听器一起使用

touch-action: none;

当事件源自元素时,将此属性应用于元素不会触发默认(滚动)行为

@Badrush——你确定吗?我在我自己的“可拖动”组件上使用它,并且touchstart触发得很好。
2021-04-29 01:33:40
touchstart如果您想识别触摸事件但不允许滚动,这似乎也会杀死事件,因此没有用。
2021-05-11 01:33:40
非常适合画布元素(只需在 html 中放置 style="touch-action: none" 即可)。有什么可以更简单的!此页面的其他解决方案对我来说失败了。谢谢!
2021-05-12 01:33:40

注意:正如@nevf 在评论中指出的那样,由于性能变化,此解决方案可能不再有效(至少在 Chrome 中)建议使用touch-action@JohnWeisz's answer也建议使用

与@Llepwryd 给出的答案类似,我使用了ontouchstart的组合ontouchmove来防止在某个元素上滚动。

原样来自我的一个项目:

window.blockMenuHeaderScroll = false;
$(window).on('touchstart', function(e)
{
    if ($(e.target).closest('#mobileMenuHeader').length == 1)
    {
        blockMenuHeaderScroll = true;
    }
});
$(window).on('touchend', function()
{
    blockMenuHeaderScroll = false;
});
$(window).on('touchmove', function(e)
{
    if (blockMenuHeaderScroll)
    {
        e.preventDefault();
    }
});

本质上,我正在做的是监听触摸开始,看看它是否开始于使用 jQuery 的另一个元素的子元素,.closest并允许它打开/关闭滚动的触摸移动。e.target指触摸开始始于元素。

您想阻止触摸移动事件的默认设置,但是您还需要在触摸事件结束时为此清除标志,否则触摸滚动事件将不起作用。

这可以在没有 jQuery 的情况下完成,但是对于我的使用,我已经有了 jQuery 并且不需要编写代码来查找元素是否具有特定的父元素。

截至 2013 年 6 月 18 日在 Android 和 iPod Touch 上的 Chrome 中测试

我发现这对我的需求有用$(".carousel").on('touchstart', function (e) { e.preventDefault(); });,可以防止在我的轮播上上下滚动:)
2021-04-21 01:33:40
Chrome 现在忽略触摸事件的 event.preventDefault(),因此这将不起作用。请参阅:developers.google.com/web/updates/2017/01/...
2021-05-12 01:33:40
感谢@nevf,我在我的回答中添加了一条注释,指出并参考了 JohnWeisz 对似乎推荐方法的回答。很高兴知道我的方法至少持续了几年。🙂
2021-05-13 01:33:40
这个太棒了!
2021-05-15 01:33:40

CSS 上有一个小“hack”,它也允许你禁用滚动:

.lock-screen {
    height: 100%;
    overflow: hidden;
    width: 100%;
    position: fixed;
}

将该类添加到正文将阻止滚动。

同意,这个解决方案也最适合我。
2021-04-20 01:33:40
这在 iphone/ipad 上对我来说非常有效。谢谢!
2021-04-27 01:33:40
这个解决方案是最好的。我尝试了被接受的和投票最多的。两者都没有奏效。这个干净,轻便。
2021-05-07 01:33:40
这在我们不需要滚动但touch-action: none;允许无法在触摸设备中滚动的滚动时有效;scrollbar-width没有实用的
2021-05-16 01:33:40
document.addEventListener('touchstart', function(e) {e.preventDefault()}, false);
document.addEventListener('touchmove', function(e) {e.preventDefault()}, false);

这应该可以防止滚动,但它也会破坏其他触摸事件,除非您定义了一种自定义方式来处理它们。

我发现只是禁用touchmove而不是将事件侦听器绑定到文档,而是将它直接绑定到画布元素,这有助于防止在使用画布时滚动,但允许touchstart工作,因为我没有阻止它。
2021-04-24 01:33:40
@newman 要成功删除它,您必须拥有与添加时完全相同的所有参数,包括 {passive: false}
2021-04-24 01:33:40
我曾用 ontouchmove 尝试过这个,它确实禁用了滚动,但我无法恢复它。
2021-05-06 01:33:40
我如何取回 touchmove?我试图打电话document.removeEventListener('touchmove', handleFn),但它不起作用。
2021-05-08 01:33:40
缺少一件重要的事情:您需要设置 {passive: false} document.addEventListener('touchstart', handleEndEventFn, { passive: false });
2021-05-13 01:33:40

最终的解决方案将被设置overflow: hidden;document.documentElement像这样:

/* element is an HTML element You want catch the touch */
element.addEventListener('touchstart', function(e) {
    document.documentElement.style.overflow = 'hidden';
});

document.addEventListener('touchend', function(e) {
    document.documentElement.style.overflow = 'auto';
});

通过overflow: hidden在触摸开始时进行设置,它可以隐藏超出窗口的所有内容,从而消除滚动任何内容的可用性(没有滚动内容)。

touchend锁可以通过设置被释放overflowauto(默认值)。

最好将它附加到,<html>因为<body>可能用于做一些造型,而且它可以让孩子们表现得出乎意料。

编辑:关于touch-action: none;- Safari根据 MDN不支持它

这在 iPad (iOS 13) 上对我有用,我一次只希望可以移动一个项目。e.preventDefault(); 似乎并没有阻止 srceen 移动。
2021-05-01 01:33:40