Javascript Firefox中的event.offsetX 在此处插入标题 函数main(){ var canvas=document.getElementById(“canvas”); canvas.addEventListener(“mousemove”,函数(e){ 如果(!e)e=window.event; var ctx=canvas.getContext(“2d”); var x=e.offsetX; 变量y=e.offsetY; ctx.fillRect(x,y,1,1); }); } 请考虑上述快速和肮脏的例子。 请注意,我的画布包含一个应用了缩放变换的div。 上述代码在任何基于webkit的浏览器上都能完美地工作。移动鼠标时,它会在画布上绘制点。 不幸的是,它在Firefox中不支持,因为它的事件模型不支持offsetX/Y属性。 如何将event.clientX(firefox也支持)中的鼠标坐标转换为画布相对坐标(考虑画布位置、转换等)? 谢谢你,卢卡。

Javascript Firefox中的event.offsetX 在此处插入标题 函数main(){ var canvas=document.getElementById(“canvas”); canvas.addEventListener(“mousemove”,函数(e){ 如果(!e)e=window.event; var ctx=canvas.getContext(“2d”); var x=e.offsetX; 变量y=e.offsetY; ctx.fillRect(x,y,1,1); }); } 请考虑上述快速和肮脏的例子。 请注意,我的画布包含一个应用了缩放变换的div。 上述代码在任何基于webkit的浏览器上都能完美地工作。移动鼠标时,它会在画布上绘制点。 不幸的是,它在Firefox中不支持,因为它的事件模型不支持offsetX/Y属性。 如何将event.clientX(firefox也支持)中的鼠标坐标转换为画布相对坐标(考虑画布位置、转换等)? 谢谢你,卢卡。,javascript,html,events,firefox,html5-canvas,Javascript,Html,Events,Firefox,Html5 Canvas,试试layerX,layerY <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title

试试layerX,layerY

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script language="javascript">
function main(){
    var canvas = document.getElementById("canvas");
    canvas.addEventListener("mousemove", function(e){
        if (!e) e = window.event;
        var ctx = canvas.getContext("2d");

        var x = e.offsetX;
        var y = e.offsetY;

        ctx.fillRect(x, y, 1, 1);
    });
}
</script>
</head>
<body onload="main();">
<div style="width: 800px; height: 600px; -webkit-transform: scale(0.75,0.75); -moz-transform: scale(0.75,0.75)">
    <canvas id="canvas" width="400px" height="400px" style="background-color: #cccccc;"></canvas>
</div>
</body>
</html>

Musa的解决方案中存在一个缺陷:想想如果
e.offsetX==0
e.layerX==undefined
会发生什么情况

var x = (e.offsetX === undefined) ? e.layerX : e.offsetX;
var y = (e.offsetY === undefined) ? e.layerY : e.offsetY;
更可靠的版本如下所示:

var x = e.offsetX || e.layerX; // x is now undefined!
 var xe=e.offsetX,ye=e.offsetY;
  if(!xe){
     xe=e.clientX - $(e.target).offset().left;
  }
  if(!ye){
    ye= e.clientY - $(e.target).offset().top;
  }
或者,因为我们可以假设,如果定义了
offsetX
,那么
offsetY
也将是:

var x = e.hasOwnProperty('offsetX') ? e.offsetX : e.layerX;
var y = e.hasOwnProperty('offsetY') ? e.offsetY : e.layerY;

不幸的是,offsetX和layerX并不完全相同,因为offsetX是当前元素中的偏移量,但layerX是与页面的偏移量。以下是我目前为此使用的修复程序:

var hasOffset = e.hasOwnProperty('offsetX'),
    x         = hasOffset ? e.offsetX : e.layerX,
    y         = hasOffset ? e.offsetY : e.layerY;
从a-一个漂亮的多边形填充是这样的:

function fixEvent(e) {
    if (! e.hasOwnProperty('offsetX')) {
        var curleft = curtop = 0;
        if (e.offsetParent) {
           var obj=e;
           do {
              curleft += obj.offsetLeft;
              curtop += obj.offsetTop;
           } while (obj = obj.offsetParent);
        }
        e.offsetX=e.layerX-curleft;
        e.offsetY=e.layerY-curtop;
    }
    return e;
}

。。其中e是从jquery事件返回的事件。显然,只有在项目中已经有Jquery的情况下,否则就必须手动执行
offset()
操作。

offset
实际上并不能直接转换为
offset
属性不考虑元素的边距。下面的代码应该说明这一点

var offX  = (e.offsetX || e.pageX - $(e.target).offset().left);

由于各种原因,没有一个非jquery版本能够完全工作。然而,在你的帮助下,我做到了:

function(e) {
    var x = e.offsetX, y = e.offsetY;
    if(e.hasOwnProperty('layerX')) {
      x = e.layerX - e.currentTarget.offsetLeft;
      y = e.layerY - e.currentTarget.offsetTop;
    }
}

但是,如果没有
layerX
layerY
字段,您会怎么做

if(!event.hasOwnProperty('offsetX')) {
    event.offsetX = event.layerX - event.currentTarget.offsetLeft;
    event.offsetY = event.layerY - event.currentTarget.offsetTop;
}

我发现除了EnotionZ和laz brannigan的最后两个答案(之前每个答案都是零票)之外,这里发布的所有答案在一个div中包含多个元素的情况下都是错误的。在我的例子中,我在一个div中包含多个canvas元素,并且我正在分别聆听每个canvas

经过大量的尝试和错误,我最终得出了正确的答案,它在FireFox和Chrome中对我来说完全相同:

var x = e.offsetX || e.layerX; // x is now undefined!
 var xe=e.offsetX,ye=e.offsetY;
  if(!xe){
     xe=e.clientX - $(e.target).offset().left;
  }
  if(!ye){
    ye= e.clientY - $(e.target).offset().top;
  }

据推测,这也适用于利润率,如EnotionZ在其帖子中指出的,但我没有尝试过。不幸的是,没有任何解决方案适合我

我发现了一个很好的实现:


如果有些人仍然需要一个解决方案,那么这个解决方案在Firefox中非常适用:

var target  = e.target || e.srcElement,
              rect    = target.getBoundingClientRect(),
              offsetX = e.clientX - rect.left,
              offsetY  = e.clientY - rect.top;

e.offsetX   = offsetX;
e.offsetY   = offsetY;

这个问题需要更新答案


首先,正如我在评论中提到的,关于所有使用
layerX
layerY
的旧答案:

“此功能是非标准的,不在标准轨道上。不要在面向Web的生产站点上使用它:它不会对每个用户都起作用。实现之间可能存在很大的不兼容性,并且行为在将来可能会改变。”

(来源:)


其次,我发现当你在Firefox中
console.log(event)
时,
offsetX
offsetY
显示0,但当你
console.log(event.offsetX)
时,它不是0。所以要小心,因为你可能被欺骗了

这种行为被解释为:

记录对象

不要使用
console.log(obj)
,使用
console.log(JSON.parse(JSON.stringify(obj))

通过这种方式,您可以确保在记录obj时看到它的值。否则,许多浏览器提供实时视图,随着值的变化不断更新。这可能不是你想要的


(还请注意,
JSON.stringify()
不会执行您想要的操作…它不会对整个事件对象进行stringify。)

OffsetX/Y行为在FireFox、Chrome/Edge中有所不同。您可能需要通过添加代码段来计算该值:

var x = e.offsetX || e.originalEvent.layerX;
var y = e.offsetY || e.originalEvent.layerY;

myRef是其最近父元素的ref。因此偏移量将是该元素(clientX)减去其父元素之间的距离。

这对我不适用,因为firefox事件有“offsetX/Y”,但两者都未定义。为了它的价值,糟糕的Mozilla!在这种情况下,请适当调整-感谢您将其标记起来。var x=e.offsetX | e.layerX | 0;是一个更简单的解决方案。layerX和offsetX不一样,如果目标是内联元素,则偏移量给出光标在元素中的位置,但返回相对于非内联父容器的layerX。不幸的是,Firefox layerX和layerY属性与其他浏览器中的不同。页面左上角有相对位置,但没有elemenet。false,它们是相对于最近的offsetParent(包括元素本身)的,只需将“position:relative”添加到要用于coordenates的元素。对我不起作用,但在FF 32.0.3上不起作用。layerX和layerY在事件中不存在。layerX和offsetX不相同,如果目标是内联元素,则偏移量给出光标在元素中的位置,但返回相对于其非内联父容器的layerX。哇。从所有答案中,只有这一个对我有效。我已经用绝对定位元素尝试过了,非常感谢你!这个主题的最佳答案是:eoffsetX=(e.offsetX | | e.clientX-$(e.target).offset().left+window.pageXOffset),eoffsetY=(e.offsetY | | e.clientY-$(e.target).offset().top+window.pageYOffset);如果您已滚动页面,此修复程序将有所帮助谢谢@Denis,您添加
y位置的回答确实帮助我修复了我的issueBug tracker页面,因为答案已更改。它说你应该使用