Why is event.preventDefault() in dragstart interrupting furthur drag events from executing? - javascript

I am trying to drag over an image and in order to stop the browser's default image drag, I am using event.preventDefault(). But for some reason it is interrupting further events like dragenter, dragover, dragend etc from executing. Why is this and How can I stop browser's default function without interrupting normal drag events.
<img src="/img/image1" id="img1"/>
jQuery
var obj=$('#ironman');
obj.on('dragstart', function (e) {
//e.preventDefault();
console.log("dragstart");
});
obj.on('dragenter', function (e) {
console.log("dragenter");
});
obj.on('dragover', function () {
console.log("dragover");
});
obj.on('dragleave', function () {
console.log("dragleave");
});
obj.on('dragend', function () {
console.log("dragend");
});
JSfiddle

This is a tough one as you are stopping native drag chain event on the element. Not sure why you want to do this, but one way to implement the native dragging is to cancel it and deal with mouse events
var obj=$('#ironman');
obj.on('mousedown', function (e) {
console.log("mousedown");
// bind to the mousemove event
obj.on('mousemove', function (e) {
console.log("mousemove");
});
});
obj.on('mouseup', function (e) {
console.log("mouseup");
// unbind the mousemove event
obj.unbind('mousemove');
});
obj.on('dragstart', function (e) {
e.preventDefault(); // cancel the native drag event chain
console.log("dragstart");
});

Related

Drag event prevent mouse event

When I'm select text and start to drag selections, mouse event like a wheel or mousemove doesn't fire. How I can catch an event while dragging?
I create a test example to check this issue, you can see it here:
https://jsfiddle.net/prevolley/3q7xwa8p/4/
<p>dasdasdasdas</p>
document.addEventListener('wheel', (event) => {
console.log('wheel', event.deltaY);
});
document.addEventListener('mousemove', (event) => {
console.log('mousemove', event.pageX);
});
I want to catch a mouse event while I drag selected text.
An image where I show the problem:
you can use event drag:
document.addEventListener('drag', (event) => {
console.log('drag', event.pageX);
});
Text

jQuery on scroll listener after click event

What is the proper way to activate an on scroll listener after a click event?
I'm currently using:
$('.button').click(function (event) {
$(window).on("scroll", someFunction);
}
someFunction = function() {
//do stuff
$(window).off("scroll"); //disable scroll listener
}
On a click event I enable the scroll listener which runs someFunction. The function does stuff and disables the scroll listener when finished. The scroll listener is enabled again on click.
My concern is that I'm not doing it right. Please advise!
Note: The scroll listener cannot run indefinitely. It starts on click and must finish at the end of myFunction.
Note: I'm not trying to detect when user stops scrolling..
You could use jQuery .one():
$('.button').on('click', function() {
$(window).one('scroll', someFunction);
});
Every single click adds an additional scroll event listener. I would encapsulate the binding with an additional variable:
var isScrollBindingActive = false;
$('.button').click(function (event) {
if (!isScrollBindingActive) {
isScrollBindingActive = true;
$(window).on("scroll", someFunction);
}
}
someFunction = function() {
//do stuff
$(window).off("scroll"); //disable scroll listener
isScrollBindingActive = false; // allow binding again if wished
}
You can do it the following way:
$('.button').click(function (event) {
$(window).bind("scroll", someFunction);
}
someFunction = function() {
//do stuff
$(window).unbind("scroll"); // remove scroll listener
}

how to target event for "shift keydown & click" on a div?

I want to control events when hovering a <div> element.
I have my code pretty much working, but I have 2 remaining problems!
When I first run the code in my JSFiddle, I need to click on the body of the document first to get the keydown to be recognised. If I run the code and hover right away and press shift nothing happens. I have it running on doc ready,so not sure why I need to click first? Anyway to get this to work right way without needing to click?
I trace out in the console the console.log('click and press'); This is getting fired each time I press shift and is not looking for a click - why is this getting fired when pressing shift when I call it within a function that says $(document).on('keydown click', function (e) {
DEMO
My JS code is as follows
$(document).ready(function () {
$(".target").hover(function () {
$(document).on('keydown click', function (e) {
if (e.shiftKey) {
// code to go here for click
console.log('click and press');
}
});
$(document).on('keydown', function (e) {
if (e.shiftKey) {
// change cursor to ne-resize
$('.target').css('cursor', 'ne-resize', 'important');
}
});
$(document).on('keyup', function (e) {
// change cursor to sw-resize
$('.target').css('cursor', 'sw-resize', 'important');
});
});
});
Thanks
Your event binding is incorrect. you can use:
Demo: http://jsfiddle.net/g9ea8/8/
Code:
$(document).ready(function () {
var hovering = false;
$(".target").hover(function () {
hovering = true;
}, function() {
hovering = false;
});
$(document).on('click', function (e) {
if (hovering && e.shiftKey) {
// code to go here for click
console.log('hovering+shift+click');
}
});
$(document).on('keydown', function (e) {
if (hovering && e.shiftKey) {
// change cursor to ne-resize
$('.target').css('cursor', 'ne-resize', 'important');
console.log('hovering+shift');
}
});
$(document).on('keyup', function (e) {
// change cursor to sw-resize
if(hovering) {
$('.target').css('cursor', 'sw-resize', 'important');
console.log('hovering+keyup');
}
});
});
The reason why you need to click first on the fiddle demo is because the frame doesn't have focus, normally this should work fine.
You shouldn't be attaching a keydown listener, you only need a to attach click, otherwise keydown will fire the event regardless of a click occurring.
Also, currently you're attaching 3 handlers every time you hover over .target, see #techfoobar's answer for a cleaner solution.

How to detect when mousemove has stopped

How is it possible to detect with an eventListener when mousemove has finished?
document.AddEventListener('mousemove', startInteractionTimer, false);
function startInteractionTimer(){
clearInterval(touchInterval);
touchInterval = setInterval(noAction, 6000);
}
I want to start the function startInteractionTimer immediately after the mousemove has ended and I would like to catch that. On the code example above, it is starting if the mouse is moved.
Thanks
Edit: Alright, I answered my own question and the script above --^ is just fine.
You could always make a custom event for it:
(function ($) {
var timeout;
$(document).on('mousemove', function (event) {
if (timeout !== undefined) {
window.clearTimeout(timeout);
}
timeout = window.setTimeout(function () {
// trigger the new event on event.target, so that it can bubble appropriately
$(event.target).trigger('mousemoveend');
}, 100);
});
}(jQuery));
Now you can just do this:
$('#my-el').on('mousemoveend', function () {
...
});
Edit:
Also, for consistency with other jQuery events:
(function ($) {
$.fn.mousemoveend = function (cb) {
return this.on('mousemoveend', cb);
});
}(jQuery));
Now you can:
$('#my-el').mousemoveend(fn);
You could try setting/clearing a timeout solely to detect the end of moving the mouse...
var x;
document.addEventListener('mousemove', function() {
if (x) clearTimeout(x);
x = setTimeout(startInteractionTimer, 200);
}, false);
How long you want to wait is up to you. I don't know how long you want to say is "the end of a mousemove"
Example: http://jsfiddle.net/jeffshaver/ZjHD6/
Here is another custom-event solution, but without jQuery. It creates an event called mousestop which will be triggered on the element that the mouse pointer is on. It will bubble up like other mouse events.
So once you have that piece of code included, you can add event listeners to any element with addEventListener('mousestop', fn):
(function (mouseStopDelay) {
var timeout;
document.addEventListener('mousemove', function (e) {
clearTimeout(timeout);
timeout = setTimeout(function () {
var event = new CustomEvent("mousestop", {
detail: {
clientX: e.clientX,
clientY: e.clientY
},
bubbles: true,
cancelable: true
});
e.target.dispatchEvent(event);
}, mouseStopDelay);
});
}(1000));
// Example use
document.getElementById('link').addEventListener('mousestop', function(e) {
console.log('You stopped your mouse while on the link');
console.log('Mouse coordinates are: ', e.detail.clientX, e.detail.clientY);
// The event will bubble up to parent elements.
});
<h1>Title</h1>
<div>
content content<br>
<a id="link" href="#">stop your mouse over this link for 1 second</a><br>
content content content
</div>

Disable other click over image

I have a list which has a jquery handler for a mouse click. I need to place an image within the list, but need a mouse click on the image to perform a different function. I was thinking some sort of unbind on mouseover and bind on mouseout but can not get it to work. Is there an easier method?
The problem I am having is it performs the two clickable events when I click the image.
JS
$(function () {
var items = $('#v-nav>ul>li').each(function (index) {
$(this).click(function () {
alert("This is a click on the list")
}
});
});
html
<li id="tab" runat="server">Keywords <a class="fake-link" onclick="alert("This is an image click")"><img id="icon" src="images/icon.gif" style="float: right; visibility:visible"/></a></li>
So any ideas how I can only have the alert from the image click? Thanks in advance!
$(function () {
var items = $('#v-nav>ul>li').each(function (index) {
$(this).click(function (e) {
if($(e.target).attr('id')==='icon')){
//call that function which runs on image click
}
else {
alert("This is a click on the list")
}
}
});
});
Edit: As puppybeard suggested here is another way if you want to have different function to run for all images in the li's
$(function () {
var items = $('#v-nav>ul>li').each(function (index) {
$(this).click(function (e) {
if($(e.target).is('img'))){
//call that function which runs on image click
}
else {
alert("This is a click on the list")
}
}
});
});
It's hard to do because of event bubbling.
Event namespaces and .on() .off() would help.
For example:
var items = $('#v-nav>ul>li');
var someFunctionToPerform = function() {
alert('Imma list click event');
}
items.on('click.someEventNameSpace', someFunctionToPerform);
items.find('img').on({
'mouseover': function() {
items.off('click.someEventNameSpace');
},
'mouseleave': function() {
items.on('click.someEventNameSpace', someFunctionToPerform);
},
'click': function() {
alert('Imma list image click event!');
}
});
This code will unbind click event for list items after mouseover event on image inside the list and bind them back after mouseleave event on image.
That's probably the hard way, but still it should work. Other answer could be buggy in IE 8- because of different dirrection of event bubbling.

Categories

Resources