asvd / dragscroll

micro library for drag-n-drop scrolling style
http://asvd.github.io/dragscroll/
MIT License
1.1k stars 166 forks source link

Prevent click propagation on drag and drop #19

Open jacquesletesson opened 8 years ago

jacquesletesson commented 8 years ago

I was wondering if anyone had an issue with click event being fired after drag and drop.

My container is a huge list of images wrapped with links to a dedicated page.

Sometimes when the drap and drop is initiated on top of the image, the click event gets fired when releasing the mouse.

Is there an easy way to prevent this from happening?

I was thinking about adding a class no-click to the container then adding a click eventListener to all children which will check if the parent has the class no-click and then stop the propagation of the event.

dioguzeda commented 7 years ago

+1

dioguzeda commented 7 years ago

I found out a "almost there" way around it. Can you guys check it?

$('.dragscroll').on('scroll', function() {
    $('.dragscroll a').one('click touch', function( event ) {
        if (event.isDefaultPrevented()) {
            $('.dragscroll a').unbind('click touch').off(event);
            return true;
        } else {
            console.log( "blocked link" );
            event.preventDefault();
        }
    });
});

$('.dragscroll a').on('click touch', function(event) {
    if (event.isDefaultPrevented()) {
        $('.dragscroll a').unbind('click touch').off(event);
        return true;
    }
});
illnr commented 7 years ago

How about this quickfix?

_window[addEventListener](
    mouseup, cont.mu = function() {
        pushed = 0;
        // HERE
        setTimeout(function(){ el.classList.remove("dragging"); }, 100);
    }, 0
);

_window[addEventListener](
    mousemove,
    cont.mm = function(e) {
        if (pushed) {
            // HERE
            el.classList.add("dragging");
            (scroller = el.scroller||el).scrollLeft -=
                newScrollX = (- lastClientX + (lastClientX=e.clientX));
            scroller.scrollTop -=
                newScrollY = (- lastClientY + (lastClientY=e.clientY));
            if (el == _document.body) {
                (scroller = _document.documentElement).scrollLeft -= newScrollX;
                scroller.scrollTop -= newScrollY;
            }
        }
    }, 0
);

Now you can check the .dragscroll for .dragging and then prevent the click action.

$('.dragscroll a').click(function(event) {
    if ($(this).closest('.dragscroll').hasClass('dragging')) {
      event.preventDefault();
      return false;
    }
  });
Hisstsu commented 7 years ago

This works perfect! Thanks iBaff.

AimeeLB commented 7 years ago

Would be great if this feature was integrated into the plugin - I'm having the same problem

illnr commented 7 years ago

For my needs, I ended up using https://github.com/cubiq/iscroll.

thomasgrist commented 7 years ago

Anybody know how you would do iBaff's solution in pure Javascript?

This bit:

$('.dragscroll a').click(function(event) {
    if ($(this).closest('.dragscroll').hasClass('dragging')) {
      event.preventDefault();
      return false;
    }
  });
thomasgrist commented 7 years ago

In addition to the query above does anybody know where I'd put the '_window[addEventListener]' code snippets from iBaff's solution? In the dragscroll.js file?

klidifia commented 7 years ago

@thomasgrist Look at the unminified version of dragscroll.js and you'll see that there are is already the _window[addEventListener] code so just replace those with what is up there. Then just include that .dragscroll a click function somewhere outside, like in your normal javascript.

alpha-and-omega commented 6 years ago

My workaround using click status variable (better hide it in local scope):

    var click_is_valid = true;
    $('.dragscroll').on('scroll', function() {
        click_is_valid = false;
    });

        // change to correct selector of the clickable element:
    $(".grid").on('mousedown', 'div.grid-item', function(e) {
        click_is_valid = true;
    });

    $(".grid").on('click', 'div.grid-item', function() {
        if(!click_is_valid) return;