简体   繁体   English

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

[英]Disable scrolling when touch moving certain element

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.我有一个页面,其中有一个部分用于绘制绘图。但是在移动浏览器上使用它时,touchmove 事件,至少是垂直事件,也在滚动页面(这会降低绘图体验)。 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)?有没有办法a)禁用和重新启用页面的滚动(这样我可以在每行开始时将其关闭,但在每行完成后将其重新打开),或b)禁用默认处理从 go 到绘制草图的 canvas 的 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 上,如果我要绘制 select canvas,或者在绘图前按住我的手指一会儿,页面不会滚动,而不是因为我在页面中编码的任何内容。

Set the touch-action CSS property to none , which works even with passive event listeners :touch-action CSS 属性设置为none ,即使与被动事件侦听器一起使用

touch-action: none;

Applying this property to an element will not trigger the default (scroll) behavior when the event is originating from that element.当事件源自元素时,将此属性应用于元素不会触发默认(滚动)行为。

Note: As pointed out in the comments by @nevf, this solution may no longer work (at least in Chrome) due to performance changes .注意:正如@nevf 在评论中指出的那样, 由于性能变化,此解决方案可能不再有效(至少在 Chrome 中)。 The recommendation is to use touch-action which is also suggested by @JohnWeisz's answer .建议使用touch-action ,@JohnWeisz's answer也建议使用它。

Similar to the answer given by @Llepwryd, I used a combination of ontouchstart and ontouchmove to prevent scrolling when it is on a certain element.与@Llepwryd 给出的答案类似,我使用了ontouchstartontouchmove的组合来防止在某个元素上滚动。

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 .closest and allowing that to turn on/off the touch movement doing scrolling.本质上,我正在做的是监听触摸开始,看看它是否开始于使用 jQuery .closest的另一个元素的子元素上,并允许它打开/关闭滚动时的触摸移动。 The e.target refers to the element that the touch start begins with. 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 中测试

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.将该类添加到正文将阻止滚动。

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

The ultimate solution would be setting overflow: hidden;最终的解决方案是设置overflow: hidden; on document.documentElement like so: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: hidden on start of touch it makes everything exceeding window hidden thus removing availability to scroll anything (no content to scroll).通过设置overflow: hidden在触摸开始时隐藏窗口之外的所有内容,从而消除滚动任何内容的可用性(没有滚动内容)。

After touchend the lock can be freed by setting overflow to auto (the default value).touchend之后,可以通过将overflow设置为auto (默认值)来释放锁。

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;编辑:关于touch-action: none; - Safari doesn't support it according to MDN . - 根据 MDN Safari 不支持它。

try overflow hidden on the thing you don't want to scroll while touch event is happening.尝试在触摸事件发生时隐藏在您不想滚动的东西上的溢出。 eg 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);

I found that ev.stopPropagation();我发现ev.stopPropagation(); worked for me.为我工作。

To my surprise, the "preventDefault()" method is working for me on latest Google Chrome (version 85) on iOS 13.7.令我惊讶的是,“preventDefault()”方法在 iOS 13.7 上的最新 Google Chrome(版本 85)上对我有用。 It also works on Safari on the same device and also working on my Android 8.0 tablet.它也适用于同一设备上的 Safari,也适用于我的 Android 8.0 平板电脑。 I am currently implemented it for 2D view on my site here: https://papercraft-maker.com我目前在我的网站上实现了它的 2D 视图: https : //papercraft-maker.com

this worked for me on iphone这在 iPhone 上对我有用

$(".owl-carousel").on('touchstart', function (e) { 
            e.preventDefault();      
   });

the modern way (2022) of doing this is using pointer events as outlined here in the mozilla docs:https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events这样做的现代方式(2022)是使用 mozilla 文档中概述的指针事件:https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events

Pointer events build on touchstart and other touch events and actually stop scroll events by default along with other improvements.指针事件建立在 touchstart 和其他触摸事件之上,并且默认情况下实际上会停止滚动事件以及其他改进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM