我想做一个小绘画应用程序使用画布。所以我需要找到鼠标在画布上的位置。


当前回答

对于使用JQuery的人:

有时,当您嵌套元素时,其中一个元素附加了事件,可能会让您难以理解浏览器将什么视为父元素。在这里,您可以指定哪个父节点。

取鼠标位置,然后从父元素的偏移位置中减去它。

var x = evt.pageX - $('#element').offset().left;
var y = evt.pageY - $('#element').offset().top;

如果你想在滚动窗格中获取页面上的鼠标位置:

var x = (evt.pageX - $('#element').offset().left) + self.frame.scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + self.frame.scrollTop();

或相对于页面的位置:

var x = (evt.pageX - $('#element').offset().left) + $(window).scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();

注意以下性能优化:

var offset = $('#element').offset();
// Then refer to 
var x = evt.pageX - offset.left;

通过这种方式,JQuery不必为每一行查找#element。

更新

在@anytimecoder的回答中有一个更新的、仅支持javascript的版本——另请参阅浏览器对getBoundingClientRect()的支持。

其他回答

在我看来,上述答案都不令人满意,所以我用的是:

// Cross-browser AddEventListener
function ael(e, n, h){
    if( e.addEventListener ){
        e.addEventListener(n, h, true);
    }else{
        e.attachEvent('on'+n, h);
    }
}

var touch = 'ontouchstart' in document.documentElement; // true if touch device
var mx, my; // always has current mouse position IN WINDOW

if(touch){
    ael(document, 'touchmove', function(e){var ori=e;mx=ori.changedTouches[0].pageX;my=ori.changedTouches[0].pageY} );
}else{
    ael(document, 'mousemove', function(e){mx=e.clientX;my=e.clientY} );
}

// local mouse X,Y position in element
function showLocalPos(e){
    document.title = (mx - e.getBoundingClientRect().left)
        + 'x'
        + Math.round(my - e.getBoundingClientRect().top);
}

如果你需要知道页面当前的Y轴滚动位置:

var yscroll = window.pageYOffset
        || (document.documentElement && document.documentElement.scrollTop)
        || document.body.scrollTop; // scroll Y position in page

对于使用JQuery的人:

有时,当您嵌套元素时,其中一个元素附加了事件,可能会让您难以理解浏览器将什么视为父元素。在这里,您可以指定哪个父节点。

取鼠标位置,然后从父元素的偏移位置中减去它。

var x = evt.pageX - $('#element').offset().left;
var y = evt.pageY - $('#element').offset().top;

如果你想在滚动窗格中获取页面上的鼠标位置:

var x = (evt.pageX - $('#element').offset().left) + self.frame.scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + self.frame.scrollTop();

或相对于页面的位置:

var x = (evt.pageX - $('#element').offset().left) + $(window).scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();

注意以下性能优化:

var offset = $('#element').offset();
// Then refer to 
var x = evt.pageX - offset.left;

通过这种方式,JQuery不必为每一行查找#element。

更新

在@anytimecoder的回答中有一个更新的、仅支持javascript的版本——另请参阅浏览器对getBoundingClientRect()的支持。

您可以简单地使用jQuery的事件。pageX和事件。使用jQuery的offset()方法获取鼠标相对于元素的位置。

  $(document).ready(function() {
    $("#myDiv").mousemove(function(event){            
      var X = event.pageX - $(this).offset().left;
      var Y = event.pageY - $(this).offset().top;
      $(".cordn").text("(" + X + "," + Y + ")");
    });
  });

你可以在这里看到一个例子:如何找到相对于元素的鼠标位置

我必须得到光标的位置在一个非常宽的div与滚动条。目标是将元素拖动到div的任意位置。

将鼠标位置放在滚动画面深处的较远位置。

$('.canvas').on('mousemove', function(e){
    $(dragElement).parent().css('top', e.currentTarget.scrollTop + e.originalEvent.clientY );
    $(dragElement).parent().css('left', e.currentTarget.scrollLeft + e.originalEvent.clientX )
});

我尝试了所有这些解决方案,由于我的特殊设置与矩阵转换容器(panzoom库)没有工作。这将返回正确的值,即使缩放和窗格:

mouseevent(e) {
 const x = e.offsetX,
       y = e.offsetY
}

但前提是没有子元素。这可以通过使用CSS使它们对事件“不可见”来规避:

.child {
   pointer-events: none;
}