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

Sco*_*ter 55 javascript touch jquery-mobile

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

我已经使用jquery-mobile vmouse处理程序作为草图,如果这有所不同.

更新:在iPhone上,如果我选择要绘制的画布,或者只是在绘制之前握住我的手指,页面不会滚动,而不是因为我在页面中编码的任何内容.

Joh*_*isz 68

touch-action CSS属性设置为none,即使对被动事件侦听器也是如此:

touch-action: none;
Run Code Online (Sandbox Code Playgroud)

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

  • @Badrush - 你确定吗?我在我自己的"可拖动"组件上使用它,并且`touchstart`发射得很好. (7认同)
  • 非常适合画布元素(只需在 html 中放置 style="touch-action: none" 即可)。有什么可以更简单的!此页面的其他解决方案对我来说失败了。谢谢! (4认同)
  • 天哪,我为此爱你:) (3认同)
  • 如果访问者没有松开鼠标,这不会阻止它移动。所以基本上,它不能在拖动时动态应用。 (3认同)
  • 这似乎也会杀死“ touchstart”事件,因此如果您想识别触摸事件但不允许滚动,则无用。 (2认同)

Tur*_*erj 41

类似于@Llepwryd给出了答案,我用的组合touch-action,并ontouchstart防止滚动时,它是有一定的元素.

从我的项目中采取原样:

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();
    }
});
Run Code Online (Sandbox Code Playgroud)

基本上,我正在做的是在触摸开始时查看它是否从一个使用jQuery的另一个孩子的元素开始,ontouchmove并允许它在滚动时打开/关闭触摸动作.该.closest指触摸开始始于元素.

您希望阻止触摸移动事件的默认值,但是您还需要在触摸事件结束时清除此标志,否则触摸滚动事件将无效.

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

截至2013-06-18,在Android和Chrome Touch上测试Chrome

  • Chrome现在会忽略触摸事件的event.preventDefault(),因此将无法使用。请参阅:https://developers.google.com/web/updates/2017/01/scrolling-intervention (2认同)

Meh*_*hdi 21

CSS上有一点"黑客",它也允许你禁用滚动:

.lock-screen {
    height: 100%;
    overflow: hidden;
    width: 100%;
    position: fixed;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这对我在iPhone / iPad上完美工作。谢谢! (2认同)

小智 18

document.addEventListener('touchstart', function(e) {e.preventDefault()}, false);
document.addEventListener('touchmove', function(e) {e.preventDefault()}, false);
Run Code Online (Sandbox Code Playgroud)

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

  • 我曾尝试使用ontouchmove,它确实禁用了滚动功能,但我无法恢复原状. (5认同)
  • 缺少一件重要的事情:你需要设置`{passive:false}``document.addEventListener('touchstart',handleEndEventFn,{passive:false});` (4认同)

小智 6

最终的解决方案将像这样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';
});
Run Code Online (Sandbox Code Playgroud)

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

设置为(默认值)后touchend可以释放锁。overflowauto

最好将其附加到后面,<html>因为<body>可能会用于进行一些样式设置,而且它可能会让孩子表现出意想不到的行为。

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