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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16348031/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 04:16:26  来源:igfitidea点击:

Disable scrolling when touch moving certain element

javascriptjquery-mobiletouch

提问by Scott Hunter

I have a page with a section to sketch a drawing in. But the touchmove events, at least the vertical ones, are also scrolling the page (which degrades the sketching experience) when using it on a mobile browser. Is there a way to either a) disable & re-enable the scrolling of the page (so I can turn it off when each line is started, but turn it back on after each is done), or b) disable the default handling of touchmove events (and presumably the scrolling) that go to the canvas the sketch is drawn in (I can't just disable them completely, as the sketching uses them)?

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

I've used jquery-mobile vmouse handlers for the sketch, if that makes a difference.

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

Update: On an iPhone, if I select the canvas to be sketched in, or just hold my finger for a bit before drawing, the page doesn't scroll, and not because of anything I coded in the page.

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

回答by John Weisz

Set the touch-actionCSS property to none, which works even with passive event listeners:

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

touch-action: none;

Applying this property to an element will not trigger the default (scroll) behavior when the event is originating from thatelement.

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

回答by Turnerj

Note:As pointed out in the comments by @nevf, this solution may no longer work (at least in Chrome) due to performance changes. The recommendation is to use touch-actionwhich is also suggested by @JohnWeisz's answer.

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

Similar to the answer given by @Llepwryd, I used a combination of ontouchstartand ontouchmoveto prevent scrolling when it is on a certain element.

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

Taken as-is from a project of mine:

原样来自我的一个项目:

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

Essentially, what I am doing is listening on the touch start to see whether it begins on an element that is a child of another using jQuery .closestand allowing that to turn on/off the touch movement doing scrolling. The e.targetrefers to the element that the touch start begins with.

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

You want to prevent the default on the touch move event however you also need to clear your flag for this at the end of the touch event otherwise no touch scroll events will work.

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

This can be accomplished without jQuery however for my usage, I already had jQuery and didn't need to code something up to find whether the element has a particular parent.

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

Tested in Chrome on Android and an iPod Touch as of 2013-06-18

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

回答by Mehdi

There is a little "hack" on CSS that also allows you to disable scrolling:

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

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

Adding that class to the body will prevent scrolling.

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

回答by Mehdi

document.addEventListener('touchstart', function(e) {e.preventDefault()}, false);
document.addEventListener('touchmove', function(e) {e.preventDefault()}, false);

This should prevent scrolling, but it will also break other touch events unless you define a custom way to handle them.

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

回答by soanvig

The ultimate solution would be setting overflow: hidden;on document.documentElementlike so:

最终的解决方案将被设置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';
});

By setting overflow: hiddenon start of touch it makes everything exceeding window hidden thus removing availability to scroll anything (no content to scroll).

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

After touchendthe lock can be freed by setting overflowto auto(the default value).

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

It is better to append this to <html>because <body>may be used to do some styling, plus it can make children behave unexpectedly.

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

EDIT: About touch-action: none;- Safari doesn't support it according to MDN.

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

回答by micahblu

I found that ev.stopPropagation();worked for me.

我发现这ev.stopPropagation();对我有用。

回答by Woody

try overflow hidden on the thing you don't want to scroll while touch event is happening. e.g set overflow hidden on Start and set it back to auto on end.

尝试在触摸事件发生时隐藏在您不想滚动的东西上的溢出。例如在开始时设置溢出隐藏并在结束时将其设置回自动。

Did you try it ? I'd be interested to know if this would work.

你试了吗?我很想知道这是否有效。

document.addEventListener('ontouchstart', function(e) {
    document.body.style.overflow = "hidden";
}, false);

document.addEventListener('ontouchmove', function(e) {
    document.body.style.overflow = "auto";
}, false);