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

时间:2013-05-02 21:28:43

标签: javascript jquery-mobile touch

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

我已经在草图中使用了jquery-mobile vmouse处理程序,如果这有所不同。

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

9 个答案:

答案 0 :(得分:50)

touch-action CSS属性设置为none,即使使用passive event listeners也是如此:

touch-action: none;

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

答案 1 :(得分:41)

  

注意:正如@nevf的评论所指出的,此解决方案可能不再有效(至少在Chrome中)due to performance changes。建议使用touch-action,这也是@ JohnWeisz answer建议的。

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

从我的一个项目中采取原样:

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-06-18起在Android和iPod Touch上使用Chrome进行测试

答案 2 :(得分:19)

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

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

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

答案 3 :(得分:18)

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

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

答案 4 :(得分:2)

Hallodorn对How to disable scrolling temporarily?的回答(令人惊讶的是,这不是公认的答案)对我有用。

答案 5 :(得分:1)

最终解决方案是在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 overflow之后,可以通过将auto设置为<html>(默认值)来释放锁定。

最好将此附加到<body>,因为touch-action: none;可能会用来做一些样式,而且可能会让孩子出现意外行为。

编辑: 关于var line = val.geometry.coordinates.reverse() - Safari不支持according to MDN

答案 6 :(得分:0)

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

你尝试过吗?我很想知道这是否有用。

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

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

答案 7 :(得分:0)

令我惊讶的是,“ preventDefault()”方法在iOS 13.7上的最新Google Chrome(版本85)上对我有效。它也可以在同一设备上的Safari上运行,也可以在我的Android 8.0平板电脑上运行。 我目前在我的网站上将其用于2D视图: https://papercraft-maker.com

答案 8 :(得分:-1)

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