문제

I'm trying for numerous days to solve the following issue.

I have a menu located on the top of the page which needed to be open using swipedown event (I'm using Hammer.js jQuery version).

Problem is, every time I try to interact using swipes I either scroll the page (swipeup) or pulling the page down same as described in the following question.

Here is what I've tried so far:

overflow: hidden; on the body element with an inner container with overflow: auto, swipe on top element still triggered document scroll.

Setting preventDefault on the document also disabled lower elements events in the DOM hierarchy and by that I had no swipe events working in the page.

Also tried using stopPropagation on the actual element when the event occurs, to prevent the bubbling up the chain for the event, the result cause the object to not respond to the events (swipes) and document scroll worked with no problems.

Any ideas how can I still keep page scroll but also when using common gestures, such as swipedown/swipeup, on specific elements that the element only will be affected?

Here is an example using JSFiddle, to better demonstrate the issue.

Would appreciate ideas/thoughts

도움이 되었습니까?

해결책

I don't know if this will help, but I've always liked to use drag more than swipe. Using Hammer on my projects, swipes were a bit finicky. And from a UX standpoint, drag feels instantaneous vs a swipe. Much like, mousedown vs mouseup/click. So in instances where it's appropriate, and I believe in the case of showing swipey menu it is, I'd opt for drag.

Replacing your example with drag rather than swipe, and also using CSS transition, -webkit-transition, rather than jQuery's animate (drag will trigger like a mousemove, vs a click or a mouseup) seemed to make it work.

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

This does still have the page overscroll. A preventDefault() on document.ontouchstart would could fix that but that breaks scrolling. You might be able to do a selective preventDefault() by checking the scrollOffset perhaps. But I guess in the long run, I'd recommend something like iScroll.

Example

Also maybe tweak the hitbox for the drag to be a bit larger. Which I did in the last example. I attached the dragdown event on the document instead of the "menu" so the menu doesn't have to be visibly bigger.

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();
    }
})

다른 팁

You should use the preventDefault function of the orginal gesture, to stop the browsers default behaviour, see here: https://github.com/EightMedia/hammer.js/wiki/Event-delegation-and-how-to-stopPropagation---preventDefaults

When you have a div element, on which you want to register swipe events, you would do the following:

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

That should prevent the scrolling of the page, but only if the swipe happens on the div element.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top