我尝试了很多天来解决以下问题。
我在页面顶部有一个菜单需要使用swipedown
事件打开(我使用的是Hammer.js jQuery版本)。
问题是,每当我尝试使用滑动进行交互时,我都会滚动页面(swipeup
)或向下拉页面,与following question中描述的相同。
以下是我迄今为止所尝试的内容:
overflow: hidden;
元素上的 body
,内部容器带有overflow: auto
,在顶部元素上滑动仍会触发文档滚动。
在文档上设置preventDefault
也禁用了DOM层次结构中的下层元素事件,并且我没有在页面中使用滑动事件。
还尝试在事件发生时对实际元素使用stopPropagation
,以防止事件链冒泡,结果导致对象无法响应事件(滑动)和文档滚动工作没问题。
任何想法如何仍然保持页面滚动,但是当使用常见手势(例如swipedown / swipeup)时,对元素仅受影响的特定元素?
这是一个使用JSFiddle的example,以更好地证明这个问题。
会欣赏想法/想法
答案 0 :(得分:2)
我不知道这是否会有所帮助,但我总是喜欢使用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;}
这仍然有页面覆盖滚动。 preventDefault()
上的document.ontouchstart
可以解决这个问题,但会打破滚动。您也许可以通过检查scrollOffset来执行选择性preventDefault()
。但我想从长远来看,我推荐像iScroll这样的东西。
也许可以调整一下这个拖动的hitbox有点大。我在上一个例子中做过的。我在文档上附加了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();
}
})
答案 1 :(得分:0)
您应该使用原始手势的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元素上发生滑动时才会出现。