Javascript: Get mouse position relative to parent element - javascript

Is there any way to get mouse position relative to it's parent element?
Let's say I have a structure:
<div id="parent">
<span class="dot"></span>
</div>
When I bring my mouse over span element I need to get its position relative to its parent element (<div id="parent">). PageX/ClientX give me position relative to page/client area, so it's not working for me.

Subtract the viewport-relative position of the parent element you can get via getBoundingClientRect() from the mouse position in the event's clientX and clientY to get relative position.
For example:
element.addEventListener("mousedown", function (e) {
let bounds = parent.getBoundingClientRect();
let x = e.clientX - bounds.left;
let y = e.clientY - bounds.top;
console.log(x, y);
});
Where element is your inner element receiving the event, and parent is your desired reference for the coordinates.

jquery offset() method handles parent positioning, so
function onsomemouseevent(e) {
var x = e.pageX - $(e.target).offset().left;
}
is plain browser abstracted jquery.

Try the offsetParent property.
Try this:
positionX = document.getElementById('childId').offsetParent.offsetLeft;
positionY = document.getElementById('childId').offsetParent.offsetLeft;

Related

Get mouse position inside an element on event: onDrop

is it possible to calculate somehow position of mouse inside an droppable container. For example mouse cursor is near right border of droppable container. I would like to know that position of mouse is to the right, or center, or left relative to the container where I wan't to drop the element
<div onDrop="handleDrop">... some content inside </div>
and js
const handleDrop = evt => {
// here I am looking to calculate the mouse position inside the container
}
The event object (evt) that is passed to your handleDrop method already contains the X and Y mouse positions at the moment of drop.
const handleDrop = evt => {
const mouseX = evt.clientX;
const mouseY = evt.clientY;
}

JavaScript - Ignore if mouse is on a textarea's "resize handle"

I have the following code for a simple draggable textarea element:
HTML:
<textarea type="text" onmousedown="mouseDown(this)"></textarea>
JavaScript:
const mouseDown = element => {
document.onmousemove = e => {
element.style.left = `${e.pageX}px`;
element.style.top = `${e.pageY}px`;
}
}
document.onmouseup = () => document.onmousemove = null;
This works great, except for one problem. Trying to resize the element, since it's a textarea, makes it become 0px by 0px and gets dragged around. How can my onmousemove function return if the mouse is on the resize handle?
Calculate the size and section of where the elements resize handle is. You can get the relative location of this area by using the elements offset height, width and page location using element.getBoundingClientRect().
Once you've found those boundaries, it simply becomes is my pointer inside of the box which I've defined to be non draggable?

Get absolute mouse position from inside iframe

I have a webpage with an iframe rendering another page (same domain). I need to get the mouse position in relation to the parent document. Keep in mind the iframe can scroll both ways. I've tried using offset with no luck.
$('#iframe').contents().find('html').on('mousemove', function (e) {
//gives me location in terms of the iframe but not the entire page.
var y = e.pageY;
//gives me 0
var y = $(this).offset().top;
//more code here....
})
One way to do it would be to get the position of the iframe in the parent window and add it to the mouse position relative to the iframe itself. Extending your code below,
var iframepos = $("#iframe").position();
$('#iframe').contents().find('html').on('mousemove', function (e) {
var x = e.clientX + iframepos.left;
var y = e.clientY + iframepos.top;
console.log(x + " " + y);
})
event.clientX, event.clientY do not work in every browser. However, jQuery has a solution which does. Also, what do you do when your iframe is inside another iframe? I have a solution which works cross browser with nested iframes.
GetPosition: function (event) {
var $body = $("body");
var offsetLeft = event.pageX - $body.scrollLeft();
var offsetTop = event.pageY - $body.scrollTop();
if (window != parent.window) {
// event was fired from inside an iframe
var $frame = parent.$("iframe#" + window.frameElement.id);
var framePos = $frame.position();
offsetLeft += framePos.left;
offsetTop += framePos.top;
}
if (parent.window != parent.parent.window) {
// event was fired from inside an iframe which is inside another iframe
var $frame = parent.parent.$("iframe#" + parent.window.frameElement.id);
var framePos = $frame.position();
offsetLeft += framePos.left;
offsetTop += framePos.top;
}
return [offsetLeft, offsetTop];
}
I wish this were a perfect solution. It works if your iframe is positioned in a fixed layout or absolutely positioned as a modal dialog. However, if your iframe is inside another absolutely positioned container, you will have to get the .position() of that container as well and add it to the total offsets.

Get position relative to parent not viewport on mousedown / touchstart

How, on mousedown or touchstart, can I get the position of the mouse relative to or within the container or element it took place in.
So, I know I can get the pageX/Y or clientX/Y from the event or on touch, the original event. But that is the positioning compared to the whole viewport. This div is absolute positioned, so how can I get it positioned within the boundaries of its container ( absolute positioned ).
So this works: http://jsfiddle.net/Fb6An/
Here is the code:
$('.dataCard').on('mousedown touchstart', function(event){
$(this).children('.ripple').show().css({'left':event.clientX || event.originalEvent.clientX, 'top':event.clientY || event.originalEvent.clientY});
});
Except it doesn't work in some elements on the full site that I am working on. On elements that are closer to the right edge of the screen, it appears more to the right and lower than the the actual mouse location. In elements to the left, it works fine.
So I was wondering how can I get the position within an element and style the .ripple there?
No need for jQuery when finding the coordinates to set as the style:
$('.dataCard').on('mousedown touchstart', function(event){
var clickX = (event.clientX || event.originalEvent.clientX),
clickY = (event.clientY || event.originalEvent.clientY);
$(this).children('.ripple').each(function(){
$(this)
.show()
.css({
left: clickX - this.offsetParent.offsetLeft,
top: clickY - this.offsetParent.offsetTop
});
});
});
Updated fiddle from #Gaby aka G. Petrioli: http://jsfiddle.net/s52u4/1/
In this particular case, using jQuery is like hitting a thumbtack with a sledge hammer.
You could use position() on your container and calculate that in combination with event.screenX, event.screenY. That's what i would do in this case. Might as well wrap it into an extension
You need to find the .offsetParent() (closest element that is positioned) and subtract its .offset() values..
$('.dataCard').on('mousedown touchstart', function(event){
var clickX = (event.clientX || event.originalEvent.clientX),
clickY = (event.clientY || event.originalEvent.clientY);
$(this).children('.ripple').each(function(){
var ripple = $(this).show(),
container = ripple.offsetParent(),
offset = container.offset(),
correctX = clickX - offset.left,
correctY = clickY - offset.top;
ripple.css({ left: correctX, top: correctY});
});
});
Demo at http://jsfiddle.net/s52u4/

How do I get the absolute position of a mouse click from an onClick event on the body?

I am trying to get the absolute position (top and left) of a mouse click relative to the browser/body, not any parent elements within the body.
I have a listener bound to the body, but e.pageX and e.pageY are giving me the position relative to a div.
Note that I can leverage jQuery and YUI functions.
Code that currently does not work correctly:
//getting the position
function _handleClick(e) {
var data = { absX: e.pageX, absY: e.pageY};
_logClickData(data);
}
//binding the function
var methods = {
init: function () {
$("body").click(_handleClick);
}
};
The commenter is correct. pageX and pageY give you the mouse position relative to the entire document not its parent div. But if you're interested you can get the position relative to the document from the position relative to a div.
Get the position of the parent div relative to the body, then add the two values.
x = parentdiv.style.left + e.pageX;
y = parentdiv.style.top + e.pageY;
(0,0)
_____________________
|
|
| __________
|----100----| |
| |---60---* |
| |__________|
|
|
* = Mouse Pointer
I made the diagram because it was fun. Not because I felt you needed one!!
Also, for the above to work you may need to parseInt.
According to this (http://docs.jquery.com/Tutorials:Mouse_Position), those should give you absolute positions. offsetX/Y gives you the relative position.
Edit November 2013: the original "Mouse Position" link seems to be broken, but the documentation for pageX contains an example that utilizes jQuery pageX/Y. The page about the offset method also contains relevant examples.
If I understood your question well this would be the solution
$("body").click(function(e){
var parentOffset = $(this).offset();
var relX = e.pageX - parentOffset.left;
var relY = e.pageY - parentOffset.top;
window.alert(relX);
window.alert(relY);
});
I guess you can use window.pageXOffset, window.pageYOffset property
document.body.addEventListener('click',(e)=>{
console.log(e.clientX + window.pageXOffset, event.clientY + window.pageYOffset)
}
)
The solution, hinted at by #Mrchief's link of http://docs.jquery.com/Tutorials:Mouse_Position, was to bind to the document and not the body element.
//binding the function
var methods = {
init: function () {
$(document).click(_handleClick);
}
};

Categories