it-swarm.com.de

event.offsetX in Firefox

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

Beachten Sie bitte das obige schnelle und schmutzige Beispiel . Bitte beachten Sie, dass meine Leinwand in einem Div enthalten ist, auf das eine Skalentransformation angewendet wurde. Der obige Code funktioniert perfekt mit jedem Webkit-basierten Browser. Beim Bewegen der Maus werden Punkte auf der Zeichenfläche gezeichnet. Leider wird dies in Firefox nicht unterstützt, da das Ereignismodell die Eigenschaften offsetX/Y nicht unterstützt. Wie kann ich Mauskoordinaten aus (möglicherweise) event.clientX transformieren (was auch in Firefox unterstützt wird) in relative Koordinaten der Leinwand, unter Berücksichtigung der Position der Leinwand, transformieren usw.? Danke, Luca.

44
lviggiani

Versuchen Sie layerX, layerY

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

GEIGE

34
Musa

Von einer JQuery Bug Tracker Seite - Eine Nice Polyfill ist diese:

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

.. wobei e das Ereignis ist, das von einem Jquery-Ereignis zurückgegeben wurde. Natürlich nur, wenn Sie Jquery bereits in Ihrem Projekt haben, ansonsten müssen Sie die Funktion offset() manuell ausführen.

77
dmp

Leider hat für mich keine Lösung funktioniert.

Ich habe eine gute Implementierung gefunden hier :

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

Leider sind offsetX und layerX nicht genau dasselbe wie offsetX ist der Offset innerhalb des aktuellen Elements, aber layerX ist der Offset von der Seite. Hier ist ein Fix, das ich derzeit verwende:

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;
}
15
Tom Fredian

Es gibt einen Fehler in Musas Lösung: Überlegen Sie, was passiert, wenn e.offsetX === 0 und e.layerX === undefined...

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

Eine robustere Version sieht wie folgt aus:

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

Oder weil wir davon ausgehen können, dass, wenn offsetX definiert ist, offsetY auch

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

offset übersetzt eigentlich nicht direkt in layer; Die offset-Eigenschaft berücksichtigt nicht den Rand des Elements. Der folgende Code sollte dies berücksichtigen.

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

Keine der Nicht-Jquery-Versionen funktioniert aus verschiedenen Gründen vollständig. Mit deiner Hilfe habe ich das jedoch zum Laufen gebracht:

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

Ich fand, dass alle hier veröffentlichten Antworten außer die letzten beiden Antworten von EnotionZ und Laz Brannigan (zuvor jeweils mit Null Stimmen) fehlerhaft waren, wenn mehrere Elemente in einem Div enthalten waren. In meinem Fall habe ich mehrere Canvas-Elemente in einem einzigen div und höre mir jede Canvas separat an.

Nach langem Ausprobieren war die letzte richtige Antwort, die für mich in FireFox und Chrome perfekt und identisch funktioniert, wie folgt:

//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);

Vermutlich wird dies auch für Margen und die von EnotionZ in seinem Beitrag angegebenen Margen funktionieren, aber das habe ich nicht versucht.

3

Aber was tun Sie, wenn es keine layerX, layerY Felder gibt?

 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;
  }
2
Abdennour TOUMI

Wenn einige noch eine Lösung benötigen, funktioniert diese in Firefox perfekt: 

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