Javascript Firefox 中的 event.offsetX

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11334452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 05:29:04  来源:igfitidea点击:

event.offsetX in Firefox

javascripthtmleventsfirefoxhtml5-canvas

提问by lviggiani

<!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>

Please consider the above quick and dirty example. Please notice that my canvas is contained by a div having a scale transform applied. The above code works perfectly on any webkit based browser. While moving the mouse it draws points on the canvas. Unfortunately it doesn't in Firefox as its event model does not support the offsetX / Y properties. How can I transform mouse coordinates from (perhaps) event.clientX (which is supported in firefox too) into canvas relative coordinates taking into account canvas position, transform etc? Thanks, Luca.

请考虑上面的快速和肮脏的例子。请注意,我的画布包含在应用了缩放变换的 div 中。上面的代码在任何基于 webkit 的浏览器上都能完美运行。移动鼠标时,它会在画布上绘制点。不幸的是,它不在 Firefox 中,因为它的事件模型不支持 offsetX / Y 属性。考虑到画布位置、变换等,如何将鼠标坐标从(也许)event.clientX(Firefox 也支持)转换为画布相对坐标?谢谢,卢卡。

采纳答案by Musa

Try layerX, layerY

试试 layerX, layerY

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

FIDDLE

小提琴

回答by dmp

From a JQuery bug tracker page- a nice polyfill is this:

JQuery 错误跟踪器页面- 一个不错的 polyfill 是这样的:

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

.. where e is the event returned from a jquery event. Obviously, only if you've got Jquery already on your project, otherwise will have to do the offset()stuff manually.

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

回答by Vyacheslav Cotruta

Unfortunately no solution worked for me.

不幸的是,没有解决方案对我有用。

I found a good implementation here:

我在这里找到了一个很好的实现:

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;

回答by Tom Fredian

Unfortunately offsetX and layerX are not exactly the same as offsetX is the offset within the current element but layerX is the offset from the page. Below is a fix I am currently using for this:

不幸的是,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;
}

回答by Mark Whitaker

There's a bug in Musa's solution: think what happens if e.offsetX === 0and e.layerX === undefined...

有一个在穆萨的解决方案的一个错误:认为,如果发生了什么e.offsetX === 0,并e.layerX === undefined...

var x = e.offsetX || e.layerX; // x is now undefined!

A more robust version is as follows:

一个更健壮的版本如下:

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

Or, because we can assume that if offsetXis defined, offsetYwill be too:

或者,因为我们可以假设 ifoffsetX已定义,offsetY也将是:

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

回答by EnotionZ

offsetactually doesn't translate directly into layer; the offsetproperty doesn't account for the element's margin. The code below should account for this.

offset实际上并没有直接翻译成layer; 该offset属性不考虑元素的边距。下面的代码应该说明这一点。

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;
    }
}

回答by br4nnigan

None of the non-jquery versions work completely for various reasons. With your help however i got this to work:

由于各种原因,没有一个非 jquery 版本可以完全工作。但是在你的帮助下,我得到了这个:

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

回答by jeremykentbgross

I found that all answers posted here exceptthe last two answers by EnotionZ and laz brannigan (previously with zero votes each) where wrong in cases where several elements were contained within a div. In my case I have several canvas elements inside of a single div and I am listening to each canvas separately.

我发现这里发布的所有答案除了EnotionZ 和 laz brannigan 的最后两个答案(以前每个答案都是零票)在 div 中包含多个元素的情况下是错误的。就我而言,我在单个 div 中有多个画布元素,并且我正在分别收听每个画布。

After considerable trial and error the final correct answer I came to, which works perfectly and identically for me in FireFox and Chrome is as follows:

经过大量的反复试验,我得出的最终正确答案在 FireFox 和 Chrome 中对我来说完全相同,如下所示:

//inside my mouse events handler:
var anOffsetX = (inEvent.offsetX !== undefined) ? inEvent.offsetX : (inEvent.layerX - inEvent.target.offsetLeft);
var anOffsetY = (inEvent.offsetY !== undefined) ? inEvent.offsetY : (inEvent.layerY - inEvent.target.offsetTop);

Presumably this will also work for margins and such as EnotionZ indicated in his post, but I have not tried that.

据推测,这也适用于利润率,例如他在帖子中指出的 EnotionZ,但我还没有尝试过。

回答by Abdennour TOUMI

But , what you will do if there is not layerX,layerYfields ?

但是,你会怎么做,如果没有layerXlayerY字段?

 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;
  }

回答by Crisoforo Gaspar

If some still needs a solutions this one works perfect in Firefox:

如果有些人仍然需要一个解决方案,那么这个在 Firefox 中可以完美运行:

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