Javascript mousemove event not triggered when in object - javascript

I hope your doing fine.
Here's my problem :
This code works fine :
var imageMover = {
mouseDown: function(e) {
e.target.addEventListener("mousemove", mouseMoved, false);
console.log('mouseDown');
},
mouseUp: function(e) {
e.target.removeEventListener("mousemove", mouseMoved, false);
console.log('mouseUp');
}
};
function mouseMoved(e) {
console.log("mouseMoved");
}
While this one is not :
var imageMover = {
mouseDown: function(e) {
e.target.addEventListener("mousemove", this.mouseMoved, false);
console.log('mouseDown');
},
mouseUp: function(e) {
e.target.removeEventListener("mousemove", this.mouseMoved, false);
console.log('mouseUp');
},
mouseMoved: function(e) {
console.log("mouseMoved");
}
};
To give a little more context: There are thumbnails you can click on.
When you click on it, the image is added to a container, and the events mouseUp and mouseDown are added to the image.
When someone click on the image, i'd like the event mouseMouve to be attached so I can follow the image position.
mouseUp and mouseDown are well attached, and well triggered, but mouseMouve only works when it is not inside my imageMover object.
It seems to be a scope problem, but I can't figure why it acts like that.
In advance, many thanks !

The this from this.mouseMoved is refering to the event target, which is the DOM element not the object storing the methods.
var imageMover = {
mouseDown: function(e) {
console.log( 'this is refering to => ', this );
e.target.addEventListener("mousemove", this.mouseMoved, false);
}
};
document.querySelector( '.container' ).addEventListener( 'mousedown', imageMover.mouseDown );
.container
{
width: 500px;
height: 100px;
border: 1px solid #000;
}
<div class="container"></div>

Related

Bind one click in jQuery mouseenter

When I click it is bind more than 5 click action.
This jQuery block are in mouseenter jquery function.
It bind more than on click.
Below is whole function.
$('.parent').mouseover(function () {
$('#elem').show();
$('#elem').on('click', function (event) {
alert('edit');
});
$(this).mouseleave(function () {
$('#elem').hide();
});
});
Your problem is that every time you put your mouse over the .parent element - you attach a new click event listener to the #elem element. If you hover that element several times (and you don't click), the click event is already attached and therefor you will get several "alerts".
Another thing to note is that with mouseover - every time you "switch" between elements that are one-inside-another (like your example) - that event is fire.
$('.parent').mouseover(function () {
console.log('mouseover fired for .parent');
$('#elem').show();
$('#elem').on('click', function (event) {
console.log('#elem clicked');
});
$(this).mouseleave(function () {
$('#elem').hide();
});
});
$('.parent1').click('#elem1', function(event) {
console.log('#elem1 clicked');
});
$('.parent1').mouseover(function () {
$('#elem1').show();
});
$('.parent1').mouseleave(function () {
$('#elem1').hide();
});
.parent, .parent1 { border: 1px solid red; width: 50px; height: 50px; margin: 25px; padding: 25px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div id="elem">
123
</div>
</div>
<div class="parent1">
<div id="elem1">
123
</div>
</div>
I had make solution from
Dekel answer
I changed this code:
$('.parent').mouseenter(function () {
$('#elem').show();
$('#elem').on('click', function (event) {
alert('edit');
setTimeout(function () {
$('#elem').unbind( "click" );
}, 100);
});
$(this).mouseleave(function () {
$('#elem').hide();
});
});
To this one: Where I bind one click per mouseenter and still can show or hide buttons
$('.parent').one('mouseenter', function () {
$('#elem').click(function (event) {
alert('edit');
});
});
$('.parent').mouseenter(function () {
$('#elem').show();
$(this).mouseleave(function () {
$('#elem').hide();
});
});

How to get mouseup event after native drag event?

The implementation of the WHATWG drag and drop supports dragstart, drag and dragend events.
The dragend event fires when the draggable object returns to the original position, e.g. try dragging the red box as far as you can and release it. The dragend (and "END!" console.log message) will not fire until the draggable element returns to the original position (this is most visible in the Safari browser).
var handle = document.querySelector('#handle');
handle.addEventListener('dragend', function () {
console.log('END!');
});
#handle {
background: #f00; width: 100px; height: 100px;
}
<div id="handle" draggable="true"></div>
How do I capture the mouseup or whatever else event that would indicate the release of the drag handle without a delay?
I have tried variations of:
var handle = document.querySelector('#handle');
handle.addEventListener('dragend', function () {
console.log('END!');
});
handle.addEventListener('mouseup', function () {
console.log('Mouseup');
});
#handle {
background: #f00; width: 100px; height: 100px;
}
<div id="handle" draggable="true"></div>
Though, "mouseup" does not fire after dragstart.
The closest I got to finding an event that would fire instantly after the release of the handle is mousemove:
var handle = document.querySelector('#handle');
handle.addEventListener('dragend', function () {
console.log('END!');
});
window.addEventListener('mousemove', function () {
console.log('I will not fire during the drag event. I will fire after handle has been released and mouse is moved.');
});
#handle {
background: #f00; width: 100px; height: 100px;
}
<div id="handle" draggable="true"></div>
The problem is that this approach requires user to move the mouse.
The workaround is to enable drop on the document.body:
// #see https://developer.mozilla.org/en-US/docs/Web/Events/dragover
document.body.addEventListener('dragover', function (e) {
// Prevent default to allow drop.
e.preventDefault();
});
document.body.addEventListener('drop', function (e) {
// Prevent open as a link for some elements.
e.preventDefault();
});
Making document.body to listen for the drop event results in dragend thinking that you will move the element to the new position upon releasing the handle. Therefore, there is no delay between handle release and dragend.

Adding New Element during `mousedown` event prevent triggering `click` event?

I am working with jquery events and I am adding a new element at the time of mousedown at the position of the mouse pointer and after adding the element the binded click event is not triggered.
Any suggestion is appreciable.
Thanks in advance.
Madhu
Code:
<div style="border:1px solid">Click</div>
<span></span>
<div class="vis" style="display:none">Hello</div>
<script>
var visualEle = $('div.vis');
visualEle.css({border:"1px solid"});
$('a').on("click", function (e) { e.preventDefault();});
$('div').on("mousedown", mDown);
$('div').on("mouseup",mUp);
function mDown(e) {
e.preventDefault();
visualEle.css({ left: 100, top: 0, display: "block" });
}
function mUp(e) {
e.preventDefault();
$('span').append('mouse up triggerd<br/>');
return false;
}
$('p').on("click",dClick);
function dClick(e) {
$('span').append('double click triggerd<br/>');
}
</script>
In the above code the click event is not triggered after the mousedown is completed.
according to this document
The click event is sent to an element when the mouse pointer is over the element, and the mouse button is pressed and released
in your case mouse point is over when mousedown happen but after that visualDiv moves under and mouse is released on this element.
possible solution I can think of thanks to #ArunPJohny is use $(this).trigger("click");
$('p').on("mousedown", function (e) {
_x = e.pageX;
_y = e.pageY;
visualDiv.css({
left: _x,
top: _y
});
$(this).trigger("click");
});
$('p').on("click", function (e) {
console.log(e.target)
});
Demo: http://jsfiddle.net/c5CRd/

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>

Stopping propagation of mousedown/mouseup from a click handler

Here's a DEMO.
I have two divs, an inner and an outer:
<div id="outer">
<div id="inner"></div>
</div>
With some CSS so you can see which is which:
#outer {
width: 250px;
height: 250px;
padding: 50px;
background: yellow;
}
#inner {
width: 250px;
height: 250px;
background: blue;
}
I try to stop propagation of mousedown and mouseup events from within a click handler like so:
$('#inner').on('click', function(e) {
e.stopPropagation();
$(this).css({'background': 'green'});
return false;
});
$('#outer').on('mousedown', function(e) {
$(this).css({'background': 'green'});
});
$('#outer').on('mouseup', function(e) {
$(this).css({'background': 'yellow'});
});
This doesn't seem possible. What does work is calling .stopPropagation from within other mousedown and mouseup calls, as shown here (another DEMO):
$('#inner').on('mousedown', function(e) {
e.stopPropagation();
return false;
});
$('#inner').on('mouseup', function(e) {
e.stopPropagation();
return false;
});
I may have already answered my own question, but I'm not sure if my approach is the best or most reasonable. Is this the right way to stop an event bubbling up to a mousedown and mouseup?
Yes. Since mouseclick and mousedown/mouseup are different events, you can't get at one from the other at all - you have to do it from within your own mousedown/mouseup handlers. What you can do is refactor that into a generic method to use in both places:
stopPropagation('#inner', 'mousedown');
stopPropagation('#inner', 'mouseup');
function stopPropagation(id, event) {
$(id).on(event, function(e) {
e.stopPropagation();
return false;
});
}

Categories

Resources