jedrzejchalubek jedrzejchalubek - 5 months ago 24
HTML Question

How to prevent click event on anchors when making touch and mouse drag events on its wrapper

How to prevent click event on anchors (redirects to href url, in demo redirecting to google) inside some wrapper when making touch and mouse drag events on this wrapper? With preventDefault and stopPropagation I can only limit bubbling up the DOM, right?

I want to disable links when dragging, and enable click while not dragging.

Here's demo with the problem.

var items = $('#items');

function start(event) {
event.preventDefault();
console.log('touchstart mousedown');
items.on('touchmove mousemove', move);
items.on('touchend mouseup', end);
return false;
}

function move(event) {
console.log('touchmove mousemove');
return false;
}

function end(event) {
console.log('touchend mouseup');
items
.off('touchmove mousemove')
.off('touchend mouseup');
return false;
}

items.on('touchstart mousedown', start);


https://jsfiddle.net/9oxr4quz/3/

Answer

I came up with two solutions:

First:

when the mousemove event is triggered, bind a click event and call preventDefault on the event object, to prevent the browser to follow the link. Turn off the jquery click handlers when the touchstart and/or mousedown are triggered.

Javascript:

var items = $('#items a'); // Notice I changed the selector here

function start(event) {
    event.preventDefault();
    console.log('touchstart mousedown');

    items.off('click');
    items.on('touchmove mousemove', move);
    items.on('touchend mouseup', end);
    return false;
}

...

function move(event) {
    items.on('click', function(event){ event.preventDefault(); });
    console.log('touchmove mousemove');
    return false;
}

...

Working demo: http://codepen.io/anon/pen/WvjrPd

Second:

Handle the click events by yourself, that way you can decide when the browser should visit another site and when should do nothing. This can be achieved by replacing the href attribute by a data-link or data-href attribute.

Now, when the touchstart or mousedown events are triggered, turn on the click events; if any of those events lead to a mousemove event, turn off the click events:

HTML:

<div id="items" class="items">
    <div class="item">
        <a data-link="http://google.com">Anchor</a>
    </div>
    <div class="item">
        <a data-link="http://google.com">Anchor</a>
    </div>
</div>

Javascript:

var items = $('#items a'); // Notice I changed the selector here

function start(event) {
    event.preventDefault();
    console.log('touchstart mousedown');

    items.on('click', click); // Turn on click events
    items.on('touchmove mousemove', move);
    items.on('touchend mouseup', end);
    return false;
}

function move(event) {
    items.off('click'); // Turn off click events
    console.log('touchmove mousemove');
    return false;
}

...

function click(event) { // Visit the corresponding link
    var link = $(this).attr('data-link');
    alert('Visit link: ' + link);

    // window.location.href = link;
}

items.on('touchstart mousedown', start);

CSS:

.item {
    background-color: gray;
}

.item + .item {
    margin-top: 10px;
}

.item a {
    cursor: pointer;
    display: inline-block;
    background-color: blue;
    color: white;
    padding: 9px;
    width: 100%;
    height: 100%;
}

Working demo: http://codepen.io/anon/pen/EjmPrJ

Comments