Mouse position of dynamic elements in jQuery - javascript

I've been looking around this for a while now with no real answer out there, my scenario:
$(document).on('click', '.slide-1', function (e) {
var offset = $(this).offset();
var left = e.pageX - this.offsetLeft;
var top = e.pageY - this.offsetTop;
console.log(left);
console.log(top);
});
I've tried all sorts, offsetLeft, offsetTop, using the offet() object in jQuery... all seem to be relative towards the document when using $(document).on (which I need to as .slide-1 is dynamic).
The problem is that when the window is resized, the values are always different and I can't pinpoint a singular mouse click position. Has anyone done this before and can give me any pointers?

Related

jQuery - how to animate draggable div towards moving cursor during drag event

I am using jquery UI draggable and want to have a draggable div animate during a drag event. Imagine that when stationary, the square div in the example is attached to a magnet. Wen you click on it and start dragging, it will not drag until a certain distance threshold is reached (distance = distance between center of div and current mouse position). After that threshold is reached, the div will animate toward the mouse and should then proceed to a normal drag event.
My problem is that when the mouse is dragged past the distance threshold at a fast enough speed, the div will start flashing because it is switching between showing the animated div and the one that is being dragged. Another problem that occurs is that if you drag the mouse fast enough and then stop, the div animates to the last recorded mouse position, but by the time the calculation is made, the mouse might already be at a different position, so the mouse is at one spot and the div is at another. Any ideas on how to make the div animate towards the mouse and then continue the drag event in one smooth transition? (also, i want the animation do be long enough so that you can see the div moving. if duration is set to 1, it works fine but I want it to be more visually appealing and smooth) Here is a demo: http://jsfiddle.net/b84wn2nf/
Here is some of the code found in the demo:
$(".dragSquare").draggable({
drag: function (event, ui) {
if($(this).hasClass("stuck")){
var mx = event.pageX;
var my = event.pageY;
ui.position.left = $(this).position().left;
ui.position.top = $(this).position().top;
var d = Math.floor(Math.sqrt(Math.pow(mx - ($(this).offset().left + ($(this).width() / 2)), 2) + Math.pow(my - ($(this).offset().top + ($(this).height() / 2)), 2)));
console.log(d)
if (d > 200) {
var animateToX = event.pageX - $(this).width() / 2;
var animateToY = event.pageY - $(this).height() / 2;
$(this).stop(true, true).animate({
left: animateToX + 'px',
top: animateToY + 'px'
}, {
/*easing: 'easeOutBounce,'*/
duration: 500,
start: function () {},
complete: function () {
$(this).removeClass("stuck");
}
});
}
}
} });
Okay, So I know I posted this a long time ago, and since then, I started to use the Snap.js SVG library instead of jQuery, which makes it much easier to cancel a drag, but before the switch, I solved the problem the only way I could: by modifying the source code.
In jquery-ui.js, locate the jQuery UI Draggable section, and then scroll down to _mouseDrag method.
What you need to do in your own code is set a global variable to tell jQuery if you want the drag behavior to be overridden. I used 'cancelDrag' as the variable name. So when its set to false, dragging behaves normally.
In _mouseDrag, you will see the following code:
this.helper[0].style.left = this.position.left + "px";
this.helper[0].style.top = this.position.top + "px";
What you need to do is wrap it in a conditional statement that depends on your boolean variable, so it looks like this:
if(!cancelDrag){
this.helper[0].style.left = this.position.left + "px";
this.helper[0].style.top = this.position.top + "px";
}
Basically, if cancelDrag is set to true, jQuery drag handler will not change the position of your element. Its not ideal, and should probably not be used, but it works. Make sure that if you modify this file, you are not using the minified source.

display top left corner of div relative to mouse click event

Using JavaScript (jQuery not available here)
How do I display the top left corner of my div relative to my mouse click location? The following seems to work until I have to scroll my page and then it becomes inaccurate.
function MyJsFx() {
var div1 = document.getElementById('noteContent');
div1.style.display = "block";
div1.style.top = event.clientY + 'px';
div1.style.left = event.clientX + 'px';
}
Use window.scrollY and window.scrollX as scrolling offsets. You can then subtract the the window scroll position from the values you already have to get a relative position value.
Somethime using javascript is not cross-browser.
You need detected browser before use method event.clientY or window.scrollY

Coordinates of HTML elements

I am going to create a selection 'lasso' that the user can use to select portions of a table. I figured that positioning a div over the region is far easier than trying to manipulate the cell borders.
If you don't understand what I mean, open up a spread sheet and drag over a region. I want the div to align perfectly with the cell borders.
I have a very good idea of how to do this, but how would I get the (x,y) coordinates (screen position) of a table cell (td)?
Use .offset() along with .height() and .width() if necessary.
var td = $(someTDReference);
var pos = td.offset();
pos.bottom = pos.top + td.height();
pos.right = pos.left + td.width();
// pos now contains top, left, bottom, and right in pixels
Edit: Not .position(), use .offset(). Updated above.
Edit: Changed pos.width() to td.width()
Hey you should be able to do it like this (jsFiddle): http://jsfiddle.net/jackrugile/YKHkX/
$('td').hover(function(){
var xPos = Math.floor($(this).offset().left);
var yPos = Math.floor($(this).offset().top);
});
The Math.floor gets rid of the crazy decimals and makes it easier to work with in my opinion. Hope that helps!
you can use pageX and pageY to trackdown the mouse cursor x , y
$("#your_div").mouseover(function(e))
{
x = e.pageX;
y = e.pageY;
}
you can set the div border to highlight the div on mouseover simply by
$("#your_div").css("border","1px solid black");
this will kinda show current div selectable effect...
that if if the div is
position:fixed and then you can read its left and top property
hope that helps you
For those who doesn't want to use jquery:
var coordinates = td.getBoundingClientRect();
console.log(coordinates.left, coordinates.top, coordinates.right, coordinates.bottom);

Mouse event: Getting mouse coords from base level element

I have a layout similar to
<div id="outer">
<div id="inner"></div>
</div>
with a mouse event for the 'outer' element.
I am accessing the mouse coords of the event using jQuery's mouseup event with the layerX and layerY values.
When a click is received on the 'inner' element, it gives the coords of the click relative to the 'inner' element. Is it possible that when a click is given to the element, it can give the mouse coords relative to the outer element
Basic overview of what I have:
$('#outer').mouseup(function(e){
// do stuff with
//e.layerX
//e.layerY
}
jQuery doesn't have a built in way to do this, however you could calculate what you are looking for in the way you are describing. However a simpler way would be to always get the mouse position relative to the document, and then subtract the #outer elements position relative to the document:
var $outer = $('#outer');
$outer.mouseup(function(e) {
var offset = $outer.offset();
var x = e.pageX - offset.left;
var y = e.pageY - offset.top;
});

jQuery hover not triggered when element is programatically moved under the mouse

I have an image with a hover effect (higher opacity when mouse is over it). It works as desired when the mouse moves in and out.
However, the image itself is moving (I'm periodically changing the css attribute top). When the mouse does not move and the image moves under the mouse cursor, no related events are triggered. That means, the hover functions are not called. I also tried using the mouseenter and mouseleave events instead, but they don't work either.
What would be a good approach to get the desired behavior (hover effect whenever the mouse is over the image, regardless of why it got there)?
You won't be able to trigger mouse events if the mouse isn't moving, though you will be able to check where the mouse is when the image is moving. What you need to do is track the mouse position in a global variable, and check to see if that position is inside your image when it moves.
jQuery has a nice article about how to do it using their library: http://docs.jquery.com/Tutorials:Mouse_Position
To find the position of your image you can use the jQuery position function: http://api.jquery.com/position/
With that position you can create a bounds using the height/width of your image. On your image move check to see if that global mouse position is inside your image bounds and you should be good to go.
This is how I would write the code(completely untested btw):
var mousex = 0;
var mousey = 0;
jQuery(document).ready(function(){
$(document).mousemove(function(e){
mousex = e.pageX;
mousey = e.pageY;
});
})
img.move(function(){
...move code...
var p = $(this).position();
if(mousex >= p.left && mousex <= p.left + $(this).width
&& mousey <= p.top && mousey >= p.top + $(this).height)
{
...opacity code...
}
});
You could manually test to see if the mouse is in the image when you move the image then fire the desired event.
Mouse position using jQuery outside of events will show you how to keep track of the mouse position. Then just find the offset of the image and see if it's inside the image.
In addition to wajiw's and ryan's answers, you should trigger the mouseenter and mouseleave events as you detect that the mouse is over/not over the image, so that whatever code you bound to .hover() is still executed:
$(".my-image").trigger("mouseenter");
$(".my-image").trigger("mouseleave");
#wajiw has posted a great solution, but unfortunately it's plagued with typos meaning it won't work out of the box until you fix it.
Here is a class you can use which is tested and works which will allow you to test if an object is under the mouse.
Class definition
// keeps track of recent mouse position and provides functionality to check if mouse is over an object
// useful for when nodes appear underneath the mouse without mouse movement and we need to trigger hover
// see http://stackoverflow.com/questions/4403518
function MouseTracker($) {
var mouseX, mouseY;
$(document).mousemove(function(e) {
mouseX = e.pageX;
mouseY = e.pageY;
});
return {
isOver: function(node) {
var p = $(node).offset();
if (mouseX >= p.left && mouseX <= p.left + $(node).width()
&& mouseY >= p.top && mouseY <= p.top + $(node).height())
{
return true;
}
return false;
}
}
}
Usage example
var mouseTracker = new MouseTracker(jQuery);
if (mouseTracker.isOver($('#my-object-in-question'))) {
$('#my-object-in-question').trigger("mouseenter");
}
Hope that helps.
I could make this into a jQuery plugin very easily if anyone wants it, just drop me a line and I'll go ahead.
Matt

Categories