I'm implementing drag and drop with jQuery.
So, after mousedown, event starts working:
On mousemove selected element moves with mouse.
Now, I want it to stop working on mouseup.
here's my code:
$(document).on("mousemove", widget, function() {
var newMouseX = event.pageX - mouseX;
var newMouseY = event.pageY - mouseY;
var newElemX = elemX + newMouseX;
var newElemY = elemY + newMouseY;
$(widget).offset({ top: newElemY , left: newElemX });
$(document).on("mouseup", widget, function(widget) {
// what to do here?
});
});
any suggestions?
Related
How can a function, which is triggered by another function, get the mouse's position? Here's my code:
function myFunction(e){
setTimeout(function(){
if(isMouseDown == true){
mouseX = e.clientX;
mouseY = e.clientY;
document.getElementById('myElement').innerHTML = mouseX + ' , ' + mouseY;
myFunction(event);
} else {}
}, 100);
}
What this does is to display the coordinates when clicked. I need it to display them every 100ms if isMouseDown == true.
Thanks
There is no way in Javascript for a random Javascript function to get the mouse position. The current mouse position only comes from an event object for a mouse-related event. So, if you want to keep track of the mouse position, then you can register an event handler for the mousemove event and for mousedown and mouseup to keep track of the button state.
If you only want to display the mouse position, ever 100ms, then you can set a timer so that it is only displayed that often, but you will need to keep track of the current mouse position in a mousemove event handler.
Here's a simple code example:
var lastMouseX = 0, lastMouseY = 0;
document.addEventListener("mousemove", function(e) {
lastMouseX = e.clientX;
lastMouseY = e.clientY;
});
var mouseTimer;
document.addEventListener("mousedown", function() {
if (!mouseTimer) {
mouseTimer = setInterval(function() {
document.getElementById("x").innerHTML = lastMouseX;
document.getElementById("y").innerHTML = lastMouseY;
}, 100);
}
});
document.addEventListener("mouseup", function() {
clearInterval(mouseTimer);
mouseTimer = null;
});
<div id="x"></div>
<div id="y"></div>
It's a bit fuzzy what you're trying to achieve, however you're not going to get a periodic event if you're usingsetTimeout(). It sounds like you're looking for setInterval(). See the below example:
var mouseX = 0;
var mouseY = 0;
var isMouseDown = true;
document.onmousemove = function(e){
mouseX = e.pageX;
mouseY = e.pageY;
}
setInterval("myFunction()", 100);
function myFunction(){
if(isMouseDown) {
document.getElementById('myElement').innerHTML = mouseX + ' , ' + mouseY;
}
}
<div id="myElement"></div>
I am using the following JS function to have hover tooltip effect. The function works excellent. Problem happens after loading certain area with ajax. I need to call this function to work on the data collected through ajax (Jquery). That is OK as well. Problem is while I close the area called through ajax, I see unexpected behavior at the base page. The previous tooltip effects now show bubble within self (image is given below).
Any idea how to prevent this conflict?
function tooltip(){
$('.master_tooltip').hover(function(){
// Hover over code
var title = $(this).attr('title');
$(this).data('tipText', title).removeAttr('title');
$('<p class="tooltip"></p>')
.text(title)
.appendTo('body')
.fadeIn('slow');
}, function() {
// Hover out code
$(this).attr('title', $(this).data('tipText'));
$('.tooltip').remove();
}).mousemove(function(e) {
var mousex = e.pageX + 20; //Get X coordinates
var mousey = e.pageY + 10; //Get Y coordinates
$('.tooltip')
.css({ top: mousey, left: mousex })
});
}
Call that function only once, otherwise the event handlers will be bound multiple times for the already existing elements.
What you need to do is rewrite it so it delegates the mouse events and works with dynamically inserted elements, like this
function tooltip(){
$(document).on({
mouseenter : function() {
var title = $(this).attr('title');
$(this).data('tipText', title).removeAttr('title');
$('<p class="tooltip"></p>').text(title)
.appendTo('body')
.fadeIn('slow');
},
mouseleave : function() {
$(this).attr('title', $(this).data('tipText'));
$('.tooltip').remove();
},
mouseover : function(e) {
var mousex = e.pageX + 20; //Get X coordinates
var mousey = e.pageY + 10; //Get Y coordinates
$('.tooltip').css({ top: mousey, left: mousex })
}
}, '.master_tooltip');
}
I am curious if binding an event to an object multiple times cause problems by stacking multiple event listeners on top of each other or do they override each other? For example if I have an attachHandlers function
function _attachHandlers() {
// Slider hover
var isDown = false;
$('.ui-slider-handle').mousedown(function () {
// Create tool tip
isDown = true;
var tt = $(document.createElement('span')).addClass('sk-tooltip');
var handle = $(this);
var left = parseInt(handle.css('left'));
var val = _convertSliderValue(Math.round(left / 5 / 14.2857));
tt.text(val);
handle.append(tt);
var newLeft = (handle.outerWidth() - tt.outerWidth()) / 2;
tt.css({
'left': newLeft
});
$(document).mousemove(function (event) {
var left = parseInt(handle.css('left'));
var val = _convertSliderValue(Math.round(left / 5 / 14.2857));
tt.text(val);
var newLeft = (handle.outerWidth() - tt.outerWidth()) / 2;
tt.css({
'left': newLeft
});
});
});
$(document).mouseup(function () {
if (isDown) {
$(document).unbind('mousemove');
$(this).find('.sk-tooltip').remove()
isDown = false;
}
});
}
I need to re-attach these handlers at some point in my code and therefore I was just going to call _attachHandlers() to re-bind them, however, I will also be re-binding the document listener for the mouseup event every time this happens. Therefore, is it alright to do this and will the event handler just get overwritten everytime or do I have to unbind the handler first before it can be re-bound?
I am drawing a line with Raphael. I have a mousedown event where I store the starting position. While the mouse is down, if the user moves it, I have a mousemove event where I keep drawing the line as the mouse moves.
Now when the mouse button is released, the line should stop. This does not happen and line keeps going on if the mouse moves even though button is released. This line must stop on mouseup. If the user does mousedown again, it should begin a new line.
I have tried many combinations with the unmouse* events, but I am missing something here.
JSFiddle at: http://jsfiddle.net/zaphod013/P33FA/5/
(This is my first date with JS/Raphael. So if you think I am totally off track here, please tell me so)
var g_masterPaper;
var g_startX;
var g_startY;
var g_line;
function initDrawing() {
g_masterPaper = Raphael(10,10,700,500);
var masterBackground = g_masterPaper.rect(10,10,600,400);
masterBackground.attr("fill", "#eee");
var drawit = function(event) {
x = event.pageX - 10;
y = event.pageY - 10;
var linepath = ("M"+g_startX+" "+g_startY+" L"+x+" "+y);
g_line.attr("path", linepath);
};
var startit = function (event) {
g_startX = event.pageX - 10;
g_startY = event.pageY - 10;
g_line = g_masterPaper.path("M"+g_startX+" "+g_startY+" L"+g_startX+" "+g_startY);
masterBackground.mousemove(drawit);
};
masterBackground.mousedown(startit);
masterBackground.mouseup(function (event) {
this.unmousedown(startit);
this.unmousemove(drawit);
});
return g_masterPaper;
}
window.onload = function () {
var paper=initDrawing();
paper.text(15,475,'Use your mouse to draw.').attr({fill:'#ff0000', 'font-size':24, 'stroke-width':1,'text-anchor':'start' });
}
I think you're on track and mostly looks fine, I would possibly just simplify your handlers, and not keep removing/adding them, it keeps handlers hard to track and debug. So I would just have one handler for down/up/move...
Edit:
jsfiddle here or here which gets around other elements capturing the mouseup event and stopping it working properly.
var drawit = function(event) {
event.preventDefault();
x = event.pageX - 10;
y = event.pageY - 10;
var linepath = ("M"+g_startX+" "+g_startY+" L"+x+" "+y);
if( g_line ) { g_line.attr("path", linepath) };
};
var startit = function (event) {
event.preventDefault();
g_startX = event.pageX - 10;
g_startY = event.pageY - 10;
g_line = g_masterPaper.path("M"+g_startX+" "+g_startY+" L"+g_startX+" "+g_startY);
};
var finish = function ( event ) {
g_line = '';
}
I'm working on a drag and drop lib and i would like to add the mouse's position variation to the dragged element's actual position instead of just setting it's position to the current cursor position in the window. This would allow me not to use position: fixed and be able to drag position relative/absolute; elements.
To know the old position of the mouse (before the mousemove handler is called) i can just store the position in a variable in the previous call to that handler using e.pageX and pageY. But what about the first time the mouse handler is moved ? How can i know the old mouse position to determine it's variation when i havn't stored that old position yet ?
A piece of code :
var $dragged = null,
$window = $(window),
oldMouseX = null,
oldMouseY = null;
var mouseMoveHandler = function(e) {
var curTop = $dragged.css('top'),
curLeft = $dragged.css('left');
$dragged.css({
top : curTop + e.pageY - oldMouseY,
left : curLeft + e.pageX - oldMouseX,
});
oldMouseX = e.pageX;
oldMouseY = e.pageY;
};
$('.Draggable')
.attr('draggable', true)
.css({userSelect: 'none'})
.on('mousedown', function() {
$dragged = $(this);
$window.bind('mousemove', mouseMoveHandler);
})
.on('mouseup', function() {
$dragged = null;
$window.unbind('mousemove', mouseMoveHandler);
})