防止 iPad 顶部页面拖动

Posted

技术标签:

【中文标题】防止 iPad 顶部页面拖动【英文标题】:Preventing iPad top page drag 【发布时间】:2014-06-28 16:31:57 【问题描述】:

我尝试了很多天来解决以下问题。

我有一个位于页面顶部的菜单,需要使用swipedown 事件打开它(我使用的是 Hammer.js jQuery 版本)。

问题是,每次我尝试使用滑动进行交互时,我要么滚动页面 (swipeup),要么像 following question 中描述的那样将页面拉下。

这是我迄今为止尝试过的:

body 元素上的overflow: hidden; 带有带有overflow: auto 的内部容器,在顶部元素上滑动仍会触发文档滚动。

在文档上设置 preventDefault 还会禁用 DOM 层次结构中的较低元素事件,因此我在页面中没有滑动事件。

还尝试在事件发生时在实际元素上使用stopPropagation,以防止事件链冒泡,结果导致对象不响应事件(滑动)并且文档滚动没有问题.

任何想法如何在仅影响元素的特定元素上使用常见手势(例如向下滑动/向上滑动)时仍然保持页面滚动?

这是一个使用 JSFiddle 的example,以更好地演示该问题。

会欣赏想法/想法

【问题讨论】:

我知道您可能正在按照规范进行设计,但请考虑向下滑动是否是打开此菜单的最佳方法。做用户测试。可以发现吗?简单的点击工作会更好吗? 目前我使用的是tap 手势,尽管swipe 会更合适,因为打开时菜单会从顶部滑动。 (滑动似乎是正常的手势) 获取一些关于哪个最好的数据 - 进行一些“水冷却器测试”。如果您需要滑动工作,则需要在整个页面上进行,而不仅仅是菜单目标 事情是,只有在 ios 设备中,才会导致滑动事件始终“冒泡”到文档(html 或正文),而 android 设备接受了他们的命运:/ 【参考方案1】:

我不知道这是否会有所帮助,但我一直喜欢使用drag 而不是swipe。在我的项目中使用 Hammer,滑动有点挑剔。从用户体验的角度来看,拖动感觉与滑动相比是即时的。很像,mousedown vs mouseup/click。所以在合适的情况下,我相信在显示滑动菜单的情况下,我会选择drag

drag 而不是swipe 替换您的示例,并且还使用CSS 过渡-webkit-transition,而不是jQuery 的动画(拖动将触发像鼠标移动,而不是点击或鼠标向上)似乎使它工作.

Hammer('.nav').on('dragdown', function(e)
    e.gesture.preventDefault()
    $(".blue").html("down")
    $('.nav').css("top":"0px");
)
.on('dragup', function(e)
    e.gesture.preventDefault()
    $(".blue").html("dragup")
    $('.nav').css("top":"-150px");
);

//Added in CSS, for .nav
.nav -webkit-transition:0.5s top;

Example

这仍然有页面过度滚动。 document.ontouchstart 上的 preventDefault() 可以解决这个问题,但这会破坏滚动。您也许可以通过检查 scrollOffset 来选择 preventDefault()。但我想从长远来看,我会推荐 iScroll 之类的东西。

Example

还可以调整碰撞框以使拖动更大一些。我在上一个例子中做了。我在文档而不是“菜单”上附加了dragdown 事件,因此菜单不必明显更大。

Hammer(document).on("dragdown",function(e)
    //calculate ratio of first touch from top
    var pos=e.gesture.startEvent.center.pageY/window.innerHeight

    if(pos<0.2)  //drag occurs in the first 20% of the screen
        menu.style.marginTop="0px" //or animate here
        e.gesture.preventDefault()
        e.gesture.stopPropagation();
    
)

【讨论】:

第一个解决方案效果很好。 swipe 看起来确实有问题。 dragup/down 成功了。谢谢! 作为一个同样热衷于滑动菜单的人,我很乐意提供帮助:)【参考方案2】:

您应该使用原始手势的 preventDefault 功能来停止浏览器的默认行为,请参见此处:https://github.com/EightMedia/hammer.js/wiki/Event-delegation-and-how-to-stopPropagation---preventDefaults

当你有一个 div 元素,你想在其上注册滑动事件时,你可以执行以下操作:

$('#swipeDiv').hammer().on("swipe", function(ev)  ev.gesture.preventDefault(); );

这应该会阻止页面滚动,但前提是滑动发生在 div 元素上。

【讨论】:

我仍然会遇到页面滚动,我将处理一个 JSFiddle 示例以更好地说明问题。

以上是关于防止 iPad 顶部页面拖动的主要内容,如果未能解决你的问题,请参考以下文章

拖动底部子视图之一时平滑更新顶部子视图(iOS)

React-DnD - 当顶部有固定元素时将元素拖动到屏幕顶部不会向上滚动页面

防止fancybox返回页面顶部

有啥办法可以防止 FormBuilder 元素滚动到页面顶部?

如何防止屏幕从PrimeNG拖动p对话框

如何阻止按钮推翻拖动手势