Firefox中的event.offsetX

lvi*_*ani 47 javascript firefox events html5 html5-canvas

<!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>
Run Code Online (Sandbox Code Playgroud)

请考虑以上快速而肮脏的例子.请注意我的画布包含一个应用了比例变换的div.以上代码适用于任何基于webkit的浏览器.移动鼠标时,它会在画布上绘制点.不幸的是,它不在Firefox中,因为它的事件模型不支持offsetX/Y属性.如何将(也许)event.clientX(在firefox中也支持)中的鼠标坐标转换为画布相对坐标,同时考虑画布位置,变换等?谢谢,卢卡.

dmp*_*dmp 78

JQuery bug跟踪器页面 - 一个很好的polyfill是这样的:

var offX  = (e.offsetX || e.pageX - $(e.target).offset().left);
Run Code Online (Sandbox Code Playgroud)

..其中e是从jquery事件返回的事件.显然,只有你已经在你的项目上有Jquery,否则将不得不offset()手动完成这些工作.

  • var eoffsetX =(e.offsetX || e.clientX - $(e.target).offset().left + window.pageXOffset),eoffsetY =(e.offsetY || e.clientY - $(e.target). offset().top + window.pageYOffset); 如果您滚动页面,此修复将有所帮助 (15认同)
  • 自答案以来,Bug跟踪器页面已更改.它说你应该使用`e.pageX`而不是`e.clientX`.它也解决了滚动页面的问题.适用于最新的Chrome,FF和IE. (9认同)
  • 哇.从所有答案中,只有这一个为我工作.我用绝对定位的元素试过这个,非常感谢你!本主题中的最佳答案 (2认同)
  • 谢谢@Denis :) (2认同)

Mus*_*usa 36

尝试layerX,layerY

var x = (e.offsetX === undefined) ? e.layerX : e.offsetX;
var y = (e.offsetY === undefined) ? e.layerY : e.offsetY;
Run Code Online (Sandbox Code Playgroud)

小提琴

  • false,它们相对于最接近的offsetParent包括元素本身,只需将"position:relative"添加到要用于coordenates的元素. (3认同)
  • 不幸的是,Firefox layerX和layerY属性与其他浏览器中的属性不同.页面有相对的左上角,但不是elemenet. (2认同)

Vya*_*uta 21

不幸的是没有解决方案适合我.

我发现这里有一个很好的实现:

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;
Run Code Online (Sandbox Code Playgroud)

  • 似乎是完美的! (2认同)

小智 15

不幸的是,offsetX和layerX并不完全相同,offsetX是当前元素中的偏移量,但是layerX是页面的偏移量.以下是我目前正在使用的修复:

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;
}
Run Code Online (Sandbox Code Playgroud)

  • +1表示非jQuery解决方案,它保持与`offsetX`和`offsetY`相同的语义. (3认同)
  • 在Firefox 26.0下,事件(e)中没有名为'offsetParent'的字段,因此初始e.offsetParent不起作用('if'被简单地忽略).解决方案可能是e.target.offsetParent (2认同)

Mar*_*ker 11

Musa解决方案中存在一个错误:想想如果e.offsetX === 0e.layerX === undefined...... 会发生什么

var x = e.offsetX || e.layerX; // x is now undefined!
Run Code Online (Sandbox Code Playgroud)

更强大的版本如下:

var x = e.hasOwnProperty('offsetX') ? e.offsetX : e.layerX;
var y = e.hasOwnProperty('offsetY') ? e.offsetY : e.layerY;
Run Code Online (Sandbox Code Playgroud)

或者,因为我们可以假设如果offsetX定义了,offsetY也将是:

var hasOffset = e.hasOwnProperty('offsetX'),
    x         = hasOffset ? e.offsetX : e.layerX,
    y         = hasOffset ? e.offsetY : e.layerY;
Run Code Online (Sandbox Code Playgroud)

  • var x = e.offsetX || e.layerX || 0; 是一个更简单的解决方案. (9认同)
  • layerX和offsetX不相同,如果目标是内联元素,则offset指定元素中光标的位置,但返回相对于非内联父容器的layerX. (2认同)