触摸移动特定元素时禁用滚动

问题描述 投票:0回答:12

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

我在草图中使用了 jquery-mobile vmouse 处理程序,如果这有什么不同的话。

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

javascript jquery-mobile touch
12个回答
248
投票

touch-action CSS 属性设置为

none
,即使使用 被动事件侦听器:

touch-action: none;

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


51
投票

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

,@JohnWeisz 的 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 中进行测试


33
投票
CSS 上有一个小“hack”,也可以让你禁用滚动:

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

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


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

这应该会阻止滚动,但它也会破坏其他触摸事件,除非您定义自定义方法来处理它们。


7
投票
最终的解决方案是将

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;

 - 根据 MDN 
,Safari 不支持它。


2
投票
https://papercraft-maker.com


1
投票

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

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



1
投票
ev.stopPropagation();

对我有用。

    


0
投票

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



0
投票
touch-action

CSS 属性没有帮助。

我所做的是当触摸开始于元素时“重定向”文档滚动到该元素。

let touch_active = false; let previous_y; let element_to_scroll = document.querySelector('#your-element'); function is_element_to_scroll_open() { // Your logic goes here. return true; } document.addEventListener('touchstart', function(e) { let open = is_element_to_scroll_open(); let within_boundaries = e.composedPath().includes(element_to_scroll); if (open && within_boundaries) { touch_active = true; previous_y = e.touches[0].clientY; } }, {passive: false}); document.addEventListener('touchmove', function(e) { if (touch_active) { e.preventDefault(); let current_y = e.touches[0].clientY; let scroll_difference = current_y - previous_y; element_to_scroll.scrollTop = element_to_scroll.scrollTop - scroll_difference; previous_y = current_y; } }, {passive: false}); document.addEventListener('touchend', function(e) { if (touch_active) { touch_active = false; previous_y = null; } }, {passive: false});



0
投票

window.addEventListener("touchmove", function (e) { e.preventDefault(); }, { passive: false });

附注仅在 Chrome 上测试。


-1
投票
https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events

指针事件基于 touchstart 和其他触摸事件构建,并且默认情况下实际上停止滚动事件以及其他改进。

© www.soinside.com 2019 - 2024. All rights reserved.