asvd/dragscroll

Prevent click propagation on drag and drop

jacquesletesson opened this issue ยท 10 comments

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.

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

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

This works perfect! Thanks iBaff.

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

illnr commented

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

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

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?

@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.

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;