防止 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 顶部页面拖动的主要内容,如果未能解决你的问题,请参考以下文章
React-DnD - 当顶部有固定元素时将元素拖动到屏幕顶部不会向上滚动页面