14

I try to get mouse position relative to an element using mousemove. It works fine, but when the mouse hover a child element, the coordinates are relative to this child. I want the mouse position relative to the parent div, not the child.

See this JSFiddle for example.

var object = document.getElementsByClassName('object'),
scene = document.getElementById('scene');

function initMove() {

for(var i=0; i<object.length; i++) {

  object[i].addEventListener("mousemove", function(event) {
    //event.stopPropagation();
    return false;
  }, false);
}

scene.addEventListener("mousemove", function (event) {
  //event.stopPropagation();
  //event.currentTarget;
  moveX = event.offsetX;
  moveY = event.offsetY;
  console.log(moveX + ' + ' + moveY);
  }, false);

}

function init() {
  initMove();
  document.onselectstart = function(){ return false; }
};

init();​

Adding event.stopPropagation() on child return no data. And I'm not sure how event.currentTarget works.

I can't use mouseenter or every other mouse only controls, because I want this to be touch friendly (by replacing mousemove by touchmove).

Any ideas?

Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
Julian
  • 698
  • 2
  • 8
  • 17

3 Answers3

7

In your above code for mousemove, try using the following for moveX and moveY:

moveX = event.clientX - scene.offsetLeft;
moveY = event.clientY - scene.offsetTop;

Also, you forgot # in $('scene').

Here is an updated JSFiddle.

Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
prashanth
  • 2,059
  • 12
  • 13
3

For future reference, you can simply create an absolute div and place it over the top, set the z-index and fix it to the top and left of the parent containing the child, then change your code to make the event handler run on selector for the input layer on top. Split your height and width values to X and Y on the cursor and it's in the center.

2

Use mousemove and the cursor coordinates to get the global mouse position. Then substract the offset of your child element from this.

var scene = $('#scene');
scene.mousemove(function(e){
    var offsetX = e.pageX - scene.offset().left;
    var offsetY = e.pageY - scene.offset().top;
});

Your whole script could look like the following tested example which lets you move to object in the scene.

jQuery(document).ready(function(){

    var scene = $('#scene');
    var object = $('.object');

    scene.mousemove(function(e){
        // get offset of object relative to scene
        var offsetX = e.pageX - scene.offset().left;
        var offsetY = e.pageY - scene.offset().top;

        // grab object in it's center (optional)
        offsetX -= object.width() / 2;
        offsetY -= object.height() / 2;

        // don't left to object out of the scene
        var maxX = scene.width() - object.width();
        var maxY = scene.height() - object.height();

        if(0 > offsetX) offsetX = 0;
        else if(offsetX > maxX) offsetX = maxX ;

        if(0 > offsetY) offsetY = 0;
        else if(offsetY > maxY) offsetY = maxY;

        // delete decimals
        offsetX = Math.floor(offsetX);
        offsetY = Math.floor(offsetY);

        // debug information
        object.html('X: ' + offsetX + '<br>Y: ' + offsetY);

        // move object
        object.css('left', offsetX).css('top', offsetY);
    });

});

Is this what you wanted to do? Here is your fiddle: http://jsfiddle.net/Bp3wH/9/ (If you like see this version with only optical improvements http://jsfiddle.net/Bp3wH/11/)

danijar
  • 32,406
  • 45
  • 166
  • 297
  • the mouse coordinates have to be relative to the main div, not the page. I think event.offsetX is the only valid way to get coordinate on this case – Julian Sep 22 '12 at 19:16
  • they are, if you substract the offset of the main div. I am working on a fiddle. Wait a minute. – danijar Sep 22 '12 at 19:17
  • Thanks but it dosen't answer my question. In your exemple, the child position is updated with the mouse position relative to the parent div, it's not what I want. I just want to get the mouse position relative to the parent div even if the mouse hover a child (like if the child dosen't exist). – Julian Sep 22 '12 at 19:30
  • Isn't that what the ouput text says? I just let the object move with the cursor. You don't have to use all of my lines. – danijar Sep 22 '12 at 19:36
  • ok if I remove the parts in your code that move the object, it works. Unfortunately, I really need a way to map the coordinates using "scene" as the event, not the document. – Julian Sep 23 '12 at 13:40
  • It is the same! Just write `scene.mousemove(function(e){ ... });` insteat of `$(document) ...`. I updated my answer because I think of it as a slightly better solution. – danijar Sep 24 '12 at 11:54
  • 1
    My question was incomplete. I can't use event.pageX in my code, because it will always return the coordinate of the event relative to the whole document. I need the coordinate relative to the scene, that's why I used event.offsetX. Thanks anyway, your code kind of works, even if I never ask the object to follow the cursor... – Julian Sep 26 '12 at 16:17