Prevent click event after drag in jQuery
I made a solution with data
and setTimeout
. Maybe better than helper classes.
<div id="dragbox"></div>
and
$(function(){
$('#dragbox').bind('click', function(){
if($(this).data('dragging')) return;
$(this).toggleClass('orange');
});
$('#dragbox').draggable({
start: function(event, ui){
$(this).data('dragging', true);
},
stop: function(event, ui){
setTimeout(function(){
$(event.target).data('dragging', false);
}, 1);
}
});
});
Check the fiddle.
Preventing click event with jQuery drag and drop
Solution is to add click handler that will prevent click to propagate on start of drag. And then remove that handler after drop is performed. The last action should be delayed a bit for click prevention to work.
Solution for sortable:
...
.sortable({
...
start: function(event, ui) {
ui.item.bind("click.prevent",
function(event) { event.preventDefault(); });
},
stop: function(event, ui) {
setTimeout(function(){ui.item.unbind("click.prevent");}, 300);
}
...
})
Solution for draggable:
...
.draggable({
...
start: function(event, ui) {
ui.helper.bind("click.prevent",
function(event) { event.preventDefault(); });
},
stop: function(event, ui) {
setTimeout(function(){ui.helper.unbind("click.prevent");}, 300);
}
...
})
Prevent click event if dragged
I think how it works is that click
fires after a mouseup
and mousedown
occur on the same element and doesn't wait to see what they do (e.g. trying to stop the click from happening).
The easiest way I've seen to stop this from happening is by disabling pointer events for that element while dragging. It changes the cursor to default while dragging which isn't optimal but that might be avoidable and this is still my fav solution. For example:
let dragTarget;let dragMouseStartX;let dragMouseStartY;let dragTargetStartX;let dragTargetStartY;
const px = v => `${v}px`;
function dragStart(e) { dragTarget = this; dragTarget.classList.add("dragging"); const rect = this.getBoundingClientRect(); dragMouseStartX = e.pageX; dragMouseStartY = e.pageY; dragTargetStartX = (window.scrollX + rect.left) | 0; dragTargetStartY = (window.scrollY + rect.top) | 0;
window.addEventListener('mousemove', dragMove, {passive: false}); window.addEventListener('mouseup', dragStop, {passive: false}); return false;}
function dragMove(e) { if (dragTarget) { e.preventDefault(); e.stopPropagation(); const x = dragTargetStartX + (e.pageX - dragMouseStartX); const y = dragTargetStartY + (e.pageY - dragMouseStartY); dragTarget.style.left = px(x); dragTarget.style.top = px(y); }}
function dragStop(e) { dragTarget.classList.remove("dragging"); dragTarget = undefined; window.removeEventListener('mousemove', dragMove); window.removeEventListener('mouseup', dragStop);}
document.querySelector('.drag').addEventListener('mousedown', dragStart);document.querySelector('.click').addEventListener('click', () => { console.log('clicked', new Date());});
body { height: 100vh; }.drag { background: blue; color: white; padding: 2em; position: absolute; user-select: none; cursor: pointer;}.click { padding: 1em; background: red;}.dragging { pointer-events: none;}
<div class="drag"><div class="click">drag and release me</div></div>
Stop event propagation from jquery Draggable stop to onclick
You can use chaining and handle it directly on the click method.
While in the dragging state, the draggable gets a new class: ui-draggable-dragging
.
$("#div")
.draggable()
.click(function(){
if ( $(this).is('.ui-draggable-dragging') ) {
return;
}
// click action here
});
How do I prevent click event when I cancel drag in jquery UI?
One way to get around is to use separate elements to trigger both the actions.
For example, we use the handle
option.
If specified, restricts dragging from starting unless the mousedown occurs on the specified element(s). Only elements that descend from the draggable element are permitted
To trigger the dragging, and a separate <span>
element to trigger the toggle functionality.
Updated Fiddle (Click the text for dragging and +
/-
for toggling)
Another hackish work around is to keep track of a boolean flag -
We can set a boolean
to true
when dragging starts, and set it back to false
after a tiny timeout inside the stop callback.
The click event will be triggered immediately when we release the mouse - So if the click is triggered by a drag, the boolean flag will still be true
since we'll only reset it after a short timeout. If it is a normal click - the flag will be false.
Updated Fiddle
var dragging = false;$("li").click(function (event) { event.stopPropagation(); $this = $(this); console.log(dragging); if (!dragging) { if ($this.children("ul").length > 0) $this.children("ul").slideToggle(); }});
$("li").draggable({ revert: false, helper: "clone", cursorAt: { top: -1, left: -1 }, start: function (event) { dragging = true; }, stop: function (event) { setTimeout(function () { dragging = false; }, 10); }});
$("span").droppable({ hoverClass: "ui-state-active", greedy: true, tolerance: "pointer", drop: function (event, ui) { var dragged = ui.draggable var target = $(this).parent()
if (target.children("ul").length == 1) { dragged.appendTo(target.children("ul")); } else { // depends upon whether I'm dragging from above or from below if (dragged.prev().is(target)) // dragging from below dragged.insertBefore(target) else dragged.insertAfter(target) }
event.stopPropagation(); },});
.ui-state-active { background-color : red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script><ul> <li><span>Test 1</span>
</li> <li> <span>Test 2</span>
<ul> <li class="A"><span>Test A</span>
</li> <li class="B"><span>Test B</span>
</li> <li class="C"><span>Test C</span>
</li> </ul> </li> <li><span>Test 3</span>
</li> <li> <span>Test 4</span>
<ul> <li><span>Test X</span>
</li> <li><span>Test Y</span>
<ul> <li><span>F</span>
</li> <li><span>G</span>
</li> <li><span>H</span>
</li> </ul> </li> <li><span>Test Z</span>
</li> </ul> </li></ul>
Prevent click event triggered when dragging
I think this issue caused by event bubbling. Try my solution
function cancelBubbleEvent(e) {
if (e) {
e.stopPropagation();
}
else {
window.event.cancelBubble = true;
}
}
//slider is draggable
$('#slider').draggable({axis: "x"});
//slider photo click event
$('#slider li').click(function(e) {
page_index = $(this).attr('class').substring(4);
tmp = parseInt(page_index);
$('#book').turn('page', tmp);
close_overlay();
// cancel event bubbling
cancelBubbleEvent(e);
})
Related Topics
How to Get a Specific Parameter from Location.Search
Capture Click on Div Surrounding an Iframe
How to Split a String into an Array of Characters
Converting JSON Results to a Date
Convert Simple Array into Two-Dimensional Array (Matrix)
Difference Between the JavaScript String Type and String Object
Angularjs $Resource Restful Example
Setting Div Width and Height in JavaScript
Firebase Callable Function + Cors
How to Convert a String into a Math Operator in JavaScript
How to Set the Id Attribute of a HTML Element Dynamically with Angularjs (1.X)
When to Use the Double Not (!!) Operator in JavaScript
Differencebetween Document and Document in JavaScript