Finden Sie die Mausposition relativ zum Element

244

Ich möchte eine kleine Mal-App mit Leinwand machen. Also muss ich die Position der Maus auf der Leinwand finden.

Ben Shelock
quelle
2
Vollständige Lösung: acko.net/blog/…
edA-qa mort-ora-y
3
Ich mag, wie kurz, aber erklärt alles, was dieser Beitrag ist.
Dwjohnston
Das ist wirklich alt, aber ich habe gerade ein GitHub-Projekt gestartet, das unter anderem genau das tut, was Sie brauchen: brainlessdeveloper.com/mouse-move-interaction-spot-js
Fausto NA

Antworten:

177

Für Benutzer von JQuery:

Wenn Sie verschachtelte Elemente haben, von denen eines mit dem Ereignis verknüpft ist, kann es manchmal verwirrend sein, zu verstehen, was Ihr Browser als übergeordnetes Element ansieht. Hier können Sie angeben, welcher Elternteil.

Sie nehmen die Mausposition und subtrahieren sie dann von der Versatzposition des übergeordneten Elements.

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

Wenn Sie versuchen, die Mausposition auf einer Seite in einem Bildlaufbereich zu ermitteln:

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

Oder die Position relativ zur Seite:

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

Beachten Sie die folgende Leistungsoptimierung:

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

Auf diese Weise muss JQuery nicht #elementfür jede Zeile nachschlagen .

Aktualisieren

Es gibt eine neuere JavaScript-Version von @anytimecoder für Browser, die getBoundingClientRect () unterstützen .

Sparkyspider
quelle
7
Hat es für Sie @ben funktioniert? Ich würde mich über eine "richtige Antwort" oder einen Kommentar darüber freuen, was für Sie immer noch nicht funktioniert. Vielleicht kann ich weiter helfen.
Sparkyspider
8
Vermeiden Sie die Verwendung von $ ('Selektor') in einem Ereignishandler, es sei denn, Sie möchten sehr langsamen Code. Wählen Sie Ihr Element vor und verwenden Sie die vorausgewählte Referenz in Ihrem Handler. Das gleiche gilt für $ (Fenster). Machen Sie das einmal und zwischenspeichern Sie es.
Austin Frankreich
2
dies ist keine notwendige Erwähnung: wenn Sie den obigen Code sind einfügen kopieren, denken Sie daran zu korrigieren var y = (evt.pageY - $('#element').offset().left) + $(window).scrollTop();zuvar y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();
Raj Nathani
77
Wie könnte das DIE Antwort sein, da die Frage nichts mit jQuery zu tun hat?
FlorianB
2
@Black, aber einige Leute fragen Dinge in Javascript anstelle von JQuery, weil JQuery in ihren Umgebungen möglicherweise nicht kompatibel ist.
Dbrree
307

Da ich keine jQuery-freie Antwort gefunden habe, die ich kopieren / einfügen konnte, habe ich folgende Lösung verwendet:

function clickEvent(e) {
  // e = Mouse click event.
  var rect = e.target.getBoundingClientRect();
  var x = e.clientX - rect.left; //x position within the element.
  var y = e.clientY - rect.top;  //y position within the element.
}

JSFiddle des vollständigen Beispiels

jederzeitcoder
quelle
2
Sie müssen das Begrenzungsrecht abrunden , um bei dieser Methode ganzzahlige Werte sicherzustellen.
Jake Cobb
2
Neue Bearbeitung sollte Bildlaufprobleme beheben (mit clientX / Y)
Erik Koopmans
6
Diese Antwort sollte abgestimmt werden. Vielen Dank jederzeitcoder und @ErikKoopmans.
Ivan
3
PSA: Der Kommentar von @mpen ist veraltet. Diese Methode funktioniert auch in Fällen mit Bildlauf. Siehe aktualisierte Version ihrer Geige: jsfiddle.net/6wcsovp2
Xharlie
4
Danke dir! Ein Hinweis: Sie brauchen e.currentTargetnicht e.target. Andernfalls werden Kinderelemente davon betroffen sein
Maxim Georgievskiy
60

Im Folgenden wird die Mauspositionsbeziehung zum Canvas-Element berechnet:

var example = document.getElementById('example'); 
example.onmousemove = function(e) { 
    var x = e.pageX - this.offsetLeft; 
    var y = e.pageY - this.offsetTop; 
}

In diesem Beispiel thisbezieht sich auf das exampleElement und eist das onmousemoveEreignis.

LindaQ
quelle
83
Vielleicht bin ich es, aber zwei Codezeilen, die das Schlüsselwort "this" verwenden, haben keinen Kontext?
Deratrius
9
Auf jeden Fall fehlt der Kontext. 'e' ist das Ereignis und 'dies' ist das Element, an das das Ereignis gebunden ist var example = document.getElementById('example'); example.onmousemove = function(e) { var X = e.pageX - this.offsetLeft; var Y = e.pageY - this.offsetTop; }
Nick Bisby
22
Dies funktioniert nicht, wenn ein untergeordnetes Element eine relative oder absolute Positionierung verwendet.
edA-qa mort-ora-y
12
Sie können das Gerät , thisan e.currentTarget, dass Sie die Position in Bezug auf das Element erhalten , dass Sie den Ereignis - Listener hinzugefügt.
Linus Unnebäck
2
Dies scheint die Position auf den sichtbaren Teil des Elements zu beziehen , nicht auf das gesamte Element. Gibt es eine Möglichkeit, dies zu berücksichtigen, wenn ein Teil des Elements im Ansichtsfenster nicht sichtbar ist und Bildlaufleisten usw. vorhanden sind?
Frabjous
37

In reinem Javascript gibt es keine Antwort, die relative Koordinaten zurückgibt, wenn das Referenzelement in anderen verschachtelt ist, was absolut positioniert sein kann. Hier ist eine Lösung für dieses Szenario:

function getRelativeCoordinates (event, referenceElement) {

  const position = {
    x: event.pageX,
    y: event.pageY
  };

  const offset = {
    left: referenceElement.offsetLeft,
    top: referenceElement.offsetTop
  };

  let reference = referenceElement.offsetParent;

  while(reference){
    offset.left += reference.offsetLeft;
    offset.top += reference.offsetTop;
    reference = reference.offsetParent;
  }

  return { 
    x: position.x - offset.left,
    y: position.y - offset.top,
  }; 

}
Atrahasis
quelle
3
Ich glaube nicht , es berücksichtigt htmlElement Offset
apieceofbart
3
Funktioniert hervorragend mit Scrolling-Containern, mit nur einer kleinen Änderung: Ersetzen while(reference !== undefined)durch while(reference). Zumindest in Chrome wird der offsetParent nicht undefined, sondern null. Nur zu überprüfen, ob referencees wahr ist, stellt sicher, dass es mit beiden undefinedund funktioniert null.
Blex
Ich würde eine weitere +1 geben, wenn ich könnte, weil ich weiß, dass es eine offsetParentEigenschaft gibt, die sich auch in anderen Situationen als sehr nützlich herausstellt!
FonzTech
Im Allgemeinen ist das Überprüfen gegen undefiniert normalerweise eine schlechte Idee
Juan Mendes
Ich denke, Sie müssen gescrollte Nachkommen subtrahieren scrollLeftund scrollTopkompensieren.
Robert
20

Eine gute Beschreibung der Schwierigkeit dieses Problems finden Sie hier: http://www.quirksmode.org/js/events_properties.html#position

Mit der dort beschriebenen Technik finden Sie die Position der Maus im Dokument. Dann überprüfen Sie einfach, ob es sich innerhalb des Begrenzungsrahmens Ihres Elements befindet, den Sie durch Aufrufen element.getBoundingClientRect()eines Objekts mit den folgenden Eigenschaften finden können : { bottom, height, left, right, top, width }. Von dort aus ist es trivial herauszufinden, ob das überhaupt in Ihrem Element passiert ist oder nicht.

David W. Keith
quelle
1
Leider schlägt dies fehl, wenn irgendeine Art von Rotation stattfindet
Eric
17

Ich habe alle diese Lösungen ausprobiert und aufgrund meines speziellen Setups mit einem matrixtransformierten Container (Panzoom-Bibliothek) hat keiner funktioniert. Dies gibt den korrekten Wert zurück, auch wenn gezoomt und geschwenkt wird:

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

Aber nur, wenn keine untergeordneten Elemente im Weg sind. Dies kann umgangen werden, indem sie mithilfe von CSS für das Ereignis "unsichtbar" gemacht werden:

.child {
   pointer-events: none;
}
Fabian von Ellerts
quelle
3
Dies ist definitiv der Weg, dies im Jahr 2019 zu tun. Die anderen Antworten sind alle mit altem, zerknittertem Gepäck beladen.
Colin D
1
@ColinD danke! Ich habe vergessen hinzuzufügen, dass dies auch in IE11 funktioniert.
Fabian von Ellerts
Das hat bei mir funktioniert. Ich bin jedoch misstrauisch, dass 1) wenige positive Bewertungen 2) höher bewertete Antworten viel komplizierter sind und 3) ich keine erklärten Nachteile sehe. Kennt jemand einen Nachteil bei der Verwendung dieses Ansatzes?
Mark E
1
@MarkE Daran ist nichts Verdächtiges. Dies ist einer der vielen Fehler von StackOverflow. Die Antworten, die Sie oben sehen, wurden viele Jahre vor dieser Antwort hier veröffentlicht, sodass sie eine enorme Aufwärtsdynamik erlangten. Sobald eine Antwort diesen Schwung gewinnt, ist es ziemlich schwer und ziemlich selten, sie zu schlagen.
Jack Giffin
9

Ich kam in dieser Frage, aber um es für meinen Fall arbeiten zu lassen (mit dragover- auf einem DOM-Elemente (nicht in meinem Fall sein Leinwand)), fand ich , dass Sie nur noch verwenden offsetXund offsetYauf dem dragover-Maus - Ereignisse .

onDragOver(event){
 var x = event.offsetX;
 var y = event.offsetY;
}
John
quelle
2
Das hat bei mir großartig funktioniert. Warum hat das niemand positiv bewertet? Ich frage mich, ob es irgendwelche Fallstricke gibt. Wenn ich welche finde, melde ich mich zurück!
Seebarsch
7
event.offsetX bezieht sich auf das Element, über dem sich der Mauszeiger gerade befindet, und nicht auf das Element, an das der Dragover-Listener angehängt ist. Wenn Sie keine verschachtelte Elementstruktur haben, ist dies in Ordnung, aber wenn Sie dies tun, wird dies nicht funktionieren.
opsb
7

Ich +1 'Mark van Wyks Antwort, als sie mich in die richtige Richtung brachte, aber nicht ganz für mich löste. Ich hatte immer noch einen Versatz beim Malen in Elementen, die in einem anderen Element enthalten waren.

Fllowing löste es für mich:

        x = e.pageX - this.offsetLeft - $(elem).offset().left;
        y = e.pageY - this.offsetTop - $(elem).offset().top;

Mit anderen Worten - ich habe einfach alle Offsets aller verschachtelten Elemente gestapelt

Matt
quelle
+1 für dich! Dies ist die Antwort, nach der ich gesucht habe. Ich hatte zwei Leinwände übereinander gestapelt und die Koordinaten waren wegen der anderen Divs alle falsch. Ich wusste, dass dies das Problem war, kannte aber nicht die Logik / Gleichung, um es zu kompensieren. Du hast gerade auch mein Problem behoben! = D danke!
Partack
5

Keine der oben genannten Antworten ist IMO zufriedenstellend, daher verwende ich Folgendes:

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

Und wenn Sie jemals die aktuelle Y-Bildlaufposition der Seite kennen müssen:

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

Wenn Sie regelmäßig Websites oder PWAs (Progressive Web Apps) für mobile Geräte und / oder Laptops / Monitore mit Touchscreens entwickeln, sind Sie hier gelandet, weil Sie möglicherweise an Mausereignisse gewöhnt sind und die manchmal schmerzhafte Erfahrung von Touch noch nicht kennen Ereignisse ... yay!

Es gibt nur 3 Regeln:

  1. Tun Sie während mousemoveoder während der touchmoveVeranstaltungen so wenig wie möglich .
  2. Tun Sie während mousedownoder während der touchstartVeranstaltungen so viel wie möglich .
  3. Brechen Sie die Weitergabe ab und verhindern Sie Standardeinstellungen für Berührungsereignisse, um zu verhindern, dass Mausereignisse auch auf Hybridgeräten ausgelöst werden.

Es ist unnötig zu erwähnen, dass touchEreignisse komplizierter sind , da es mehrere geben kann und sie flexibler (komplizierter) sind als Mausereignisse. Ich werde hier nur eine einzige Berührung behandeln. Ja, ich bin faul, aber es ist die häufigste Art der Berührung.

var posTop;
var posLeft;
function handleMouseDown(evt) {
  var e = evt || window.event; // Because Firefox, etc.
  posTop = e.target.offsetTop;
  posLeft = e.target.offsetLeft;
  e.target.style.background = "red";
  // The statement above would be better handled by CSS
  // but it's just an example of a generic visible indicator.
}
function handleMouseMove(evt) {
  var e = evt || window.event;
  var x = e.offsetX; // Wonderfully
  var y = e.offsetY; // Simple!
  e.target.innerHTML = "Mouse: " + x + ", " + y;
  if (posTop)
    e.target.innerHTML += "<br>" + (x + posLeft) + ", " + (y + posTop);
}
function handleMouseOut(evt) {
  var e = evt || window.event;
  e.target.innerHTML = "";
}
function handleMouseUp(evt) {
  var e = evt || window.event;
  e.target.style.background = "yellow";
}
function handleTouchStart(evt) {
  var e = evt || window.event;
  var rect = e.target.getBoundingClientRect();
  posTop = rect.top;
  posLeft = rect.left;
  e.target.style.background = "green";
  e.preventDefault(); // Unnecessary if using Vue.js
  e.stopPropagation(); // Same deal here
}
function handleTouchMove(evt) {
  var e = evt || window.event;
  var pageX = e.touches[0].clientX; // Touches are page-relative
  var pageY = e.touches[0].clientY; // not target-relative
  var x = pageX - posLeft;
  var y = pageY - posTop;
  e.target.innerHTML = "Touch: " + x + ", " + y;
  e.target.innerHTML += "<br>" + pageX + ", " + pageY;
  e.preventDefault();
  e.stopPropagation();
}
function handleTouchEnd(evt) {
  var e = evt || window.event;
  e.target.style.background = "yellow";
  // Yes, I'm being lazy and doing the same as mouseout here
  // but obviously you could do something different if needed.
  e.preventDefault();
  e.stopPropagation();
}
div {
  background: yellow;
  height: 100px;
  left: 50px;
  position: absolute;
  top: 80px;
  user-select: none; /* Disable text selection */
  -ms-user-select: none;
  width: 100px;
}
<div 
  onmousedown="handleMouseDown()" 
  onmousemove="handleMouseMove()"
  onmouseout="handleMouseOut()"
  onmouseup="handleMouseUp()" 
  ontouchstart="handleTouchStart()" 
  ontouchmove="handleTouchMove()" 
  ontouchend="handleTouchEnd()">
</div>
Move over box for coordinates relative to top left of box.<br>
Hold mouse down or touch to change color.<br>
Drag to turn on coordinates relative to top left of page.

Verwenden Sie lieber Vue.js ? Ich mache! Dann würde Ihr HTML so aussehen:

<div @mousedown="handleMouseDown"
     @mousemove="handleMouseMove"
     @mouseup="handleMouseUp"
     @touchstart.stop.prevent="handleTouchStart"
     @touchmove.stop.prevent="handleTouchMove"
     @touchend.stop.prevent="handleTouchEnd">
John T.
quelle
3

Sie können es durch bekommen

var element = document.getElementById(canvasId);
element.onmousemove = function(e) {
    var xCoor = e.clientX;
    var yCoor = e.clientY;
}
Rob Waminal
quelle
Funktioniert dies im IE oder verwendet der IE weiterhin window.event, anstatt das Ereignis an das erste Argument des Listeners zu übergeben? edit - Ich denke, IE fehlt das Canvas-Element sowieso bis Version 9, aber dies sollte wahrscheinlich immer noch IE unterstützen, weil Dinge wie Excanvas ...
Dagg Nabbit
21
Dies gibt die Koordinaten relativ zum Browserfenster, müssen noch herausfinden, ob sie im Element mit element.getBoundingClientRect ()
David W. Keith
Danke, dass du mich auf getBoundingClientRect aufmerksam gemacht hast !!!! Ich habe nie bemerkt, dass es so etwas gibt!
Gershom
@ DavidW.Keith Kommentar sollte wirklich als die richtige Antwort angesehen werden!
Ulrik. S
3

Entnommen aus diesem Tutorial , mit Korrekturen dank des Top-Kommentars:

function getMousePos( canvas, evt ) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: Math.floor( ( evt.clientX - rect.left ) / ( rect.right - rect.left ) * canvas.width ),
        y: Math.floor( ( evt.clientY - rect.top ) / ( rect.bottom - rect.top ) * canvas.height )
    };
}

Verwenden Sie auf einer Leinwand wie folgt:

var canvas = document.getElementById( 'myCanvas' );
canvas.addEventListener( 'mousemove', function( evt ) {
    var mousePos = getMousePos( canvas, evt );
} );
Jonathan H.
quelle
3

Mir ist klar, dass ich etwas spät dran bin, aber dies funktioniert mit PURE-Javascript und gibt Ihnen sogar die Koordinaten des Zeigers innerhalb des Elements an, wenn das Element größer als das Ansichtsfenster ist und der Benutzer einen Bildlauf durchgeführt hat.

var element_offset_x ; // The distance from the left side of the element to the left of the content area


....// some code here (function declaration or element lookup )



element_offset_x = element.getBoundingClientRect().left  -  document.getElementsByTagName("html")[0].getBoundingClientRect().left  ;

....// code here 




function mouseMoveEvent(event) 
{
   var pointer_location = (event.clientX + window.pageXOffset) - element_offset_x ; 
}

Wie es funktioniert.

Als erstes ermitteln wir die Position des HTML-Elements (des Inhaltsbereichs) relativ zum aktuellen Ansichtsfenster. Wenn die Seite Bildlaufleisten hat und gescrollt wird, wird die Nummer von zurückgegebengetBoundingClientRect().left für das HTML-Tag zurückgegebene negativ. Wir verwenden diese Zahl dann, um den Abstand zwischen dem Element und der linken Seite des Inhaltsbereichs zu berechnen. Mitelement_offset_x = element.getBoundingClientRect().left......;

Kenntnis des Abstands des Elements vom Inhaltsbereich. event.clientXgibt uns den Abstand des Zeigers vom Ansichtsfenster. Es ist wichtig zu verstehen, dass das Ansichtsfenster und der Inhaltsbereich zwei verschiedene Entitäten sind. Das Ansichtsfenster kann verschoben werden, wenn die Seite gescrollt wird. Daher gibt clientX die gleiche Nummer zurück, auch wenn die Seite gescrollt wird.

Um dies zu kompensieren, müssen wir die x-Position des Zeigers (relativ zum Ansichtsfenster) zur x-Position des Ansichtsfensters (relativ zum Inhaltsbereich) hinzufügen. Die X-Position des Ansichtsfensters wird mit gefunden window.pageXOffset.

FutureSci
quelle
1
Vielen Dank, dass Sie der einzige Antwortende sind, der über das Scrollen nachdenkt. Ändern Sie Ihre Antwort, um auch die y-Achse hinzuzufügen.
Frabjous
3

Basierend auf der Lösung von @ Spider lautet meine Nicht-JQuery-Version wie folgt:

// Get the container element's bounding box
var sides = document.getElementById("container").getBoundingClientRect();

// Apply the mouse event listener
document.getElementById("canvas").onmousemove = (e) => {
  // Here 'self' is simply the current window's context
  var x = (e.clientX - sides.left) + self.pageXOffset;
  var y = (e.clientY - sides.top) + self.pageYOffset;
}

Dies funktioniert sowohl beim Scrollen als auch beim Zoomen (in diesem Fall werden manchmal Floats zurückgegeben).

Letokteren
quelle
Ich würde positiv stimmen, aber sollten das nicht Minuszeichen für die Seitenversätze sein? Entweder das oder die Klammern um den zweiten Teil?
Chris Sunami unterstützt Monica
1

Die Mauskoordinaten innerhalb einer Zeichenfläche können dank event.offsetX und event.offsetY abgerufen werden. Hier ist ein kleiner Ausschnitt, um meinen Standpunkt zu beweisen:

c=document.getElementById("c");
ctx=c.getContext("2d");
ctx.fillStyle="black";
ctx.fillRect(0,0,100,100);
c.addEventListener("mousemove",function(mouseEvt){
  // the mouse's coordinates on the canvas are just below
  x=mouseEvt.offsetX;
  y=mouseEvt.offsetY;
  // the following lines draw a red square around the mouse to prove it
  ctx.fillStyle="black";
  ctx.fillRect(0,0,100,100);
  ctx.fillStyle="red";
  ctx.fillRect(x-5,y-5,10,10);
});
  
body {
  background-color: blue;
}

canvas {
  position: absolute;
  top: 50px;
  left: 100px;
}
<canvas id="c" width="100" height="100"></canvas>
    

Nino Filiu
quelle
Es funktioniert nicht, wenn ein anderer Div die Leinwand überlagert, genau wie @opsb sagte
David Peicho
1
canvas.onmousedown = function(e) {
    pos_left = e.pageX - e.currentTarget.offsetLeft;
    pos_top = e.pageY - e.currentTarget.offsetTop;
    console.log(pos_left, pos_top)
}

HTMLElement.offsetLeft

Die HTMLElement.offsetLeftschreibgeschützte Eigenschaft gibt die Anzahl der Pixel zurück, um die die obere linke Ecke des aktuellen Elements innerhalb der nach links versetzt istHTMLElement.offsetParent Knotens .

Für Block-Elemente, offsetTop, offsetLeft, offsetWidth, und offsetHeightdie Grenze Kasten eines Elements relativ zum beschreiben offsetParent.

Für Elemente auf Inline-Ebene (z. B. span), die von einer Zeile zur nächsten umbrechen können offsetTopund offsetLeftdie Positionen des ersten Rahmenrahmens beschreiben (verwenden Element.getClientRects(), um dessen Breite und Höhe zu ermitteln), während offsetWidthund offsetHeightdie Abmessungen des Begrenzungsrahmens beschreiben (verwenden Element.getBoundingClientRect(), um seine Position zu erhalten). Daher ist ein Kasten mit der linken, oberen, Breite und Höhe offsetLeft, offsetTop, offsetWidthund offsetHeightnicht ein Begrenzungsrahmen für eine Spanne mit umwickeltem Text sein.

HTMLElement.offsetTop

Die HTMLElement.offsetTopschreibgeschützte Eigenschaft gibt den Abstand des aktuellen Elements zum oberen Rand des offsetParentKnotens zurück.

MouseEvent.pageX

Die pageXschreibgeschützte Eigenschaft gibt die X-Koordinate (horizontal) in Pixel des Ereignisses relativ zum gesamten Dokument zurück. Diese Eigenschaft berücksichtigt jedes horizontale Scrollen der Seite.

MouseEvent.pageY

Die MouseEvent.pageYschreibgeschützte Eigenschaft gibt die Y-Koordinate (vertikal) in Pixel des Ereignisses relativ zum gesamten Dokument zurück. Diese Eigenschaft berücksichtigt jedes vertikale Scrollen der Seite.

Weitere Erläuterungen finden Sie im Mozilla Developer Network:

https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageX https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageY https: // developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetLeft https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop

lama12345
quelle
Während dieses Code-Snippet die Frage lösen kann, hilft das Hinzufügen einer Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen.
Patrick Hund
Ich hoffe wirklich, dass die Leser in Zukunft eine JS-API haben, die dies für sie berechnet. ;-) Dies ist wahrscheinlich die einfachste, vollständigste und in sich geschlossene Antwort. Das Kommentieren eines selbsterklärenden Codes lenkt nur die Verschwendung ab.
Lama12345
Ich stimme der Bitte von @ PatrickHund um eine Erklärung zu. Ich bin kein CSS / JS-Experte und weiß mehr über die Beziehungen zwischen z. B. pageund offsetwäre für mich sehr hilfreich. Vielen Dank, dass Sie diese Anfrage berücksichtigt haben!
cxw
@cxw Ok, du bist jetzt der 2. Downvote (hatte 1 Upvote) ... Ich habe jetzt eine lange Erklärung hinzugefügt, es ist ungefähr 10x so lang wie die 4 Codezeilen. Gern geschehen, viel Spaß beim Lesen. Ich habe Ihre Anfrage berücksichtigt! : p
lama12345
1
@cxw Ich habe herumgespielt, indem ich ein zusätzliches absolut positioniertes Element hinzugefügt und das Canvas-Element selbst auch außerhalb des Bildschirms gezwungen habe, also musste ich dorthin scrollen, wie links / oben 2000px außerhalb des Bildschirms. Dieser Code konnte nicht beschädigt werden.
Lama12345
1

Ich habe eine andere Lösung implementiert, die ich für sehr einfach halte, also dachte ich, ich würde sie mit euch teilen.

Das Problem für mich war also, dass das gezogene Div für den Mauszeiger auf 0,0 springen würde . Also musste ich die Position der Maus auf dem Div erfassen, um die neue Position des Divs anzupassen.

Ich lese die Divs PageX und PageY und setze den oberen und linken Rand entsprechend ein. Um dann die Werte zum Anpassen der Koordinaten zu erhalten, um den Cursor an der Anfangsposition im Div zu halten, verwende ich einen onDragStart-Listener und speichere das e.nativeEvent .layerX und e.nativeEvent.layerY , die nur im anfänglichen Trigger die Position der Maus innerhalb des ziehbaren Div angeben.

Beispielcode:

 onDrag={(e) => {
          let newCoords;
          newCoords = { x: e.pageX - this.state.correctionX, y: e.pageY - this.state.correctionY };
          this.props.onDrag(newCoords, e, item.id);
        }}
        onDragStart={
          (e) => {
            this.setState({
              correctionX: e.nativeEvent.layerX,
              correctionY: e.nativeEvent.layerY,
            });
          }

Ich hoffe, das hilft jemandem, der die gleichen Probleme hatte wie ich :)

Athinodoros Sgouromallis
quelle
1
function myFunction(e) {
    var x =  e.clientX - e.currentTarget.offsetLeft ; 
    var y = e.clientY - e.currentTarget.offsetTop ;
}

das funktioniert ok!

M9J_cfALt
quelle
0

Sie müssen die Struktur Ihrer Seite kennen, denn wenn Ihre Leinwand ein Kind eines Div ist, das wiederum ein Kind eines anderen Div ist, wird die Geschichte komplizierter. Hier ist mein Code für eine Leinwand, die sich innerhalb von 2 Ebenen von div s befindet:

canvas.addEventListener("click", function(event) {
var x = event.pageX - (this.offsetLeft + this.parentElement.offsetLeft);
var y = event.pageY - (this.offsetTop + this.parentElement.offsetTop);
console.log("relative x=" + x, "relative y" + y);

});

Eli Mashiah
quelle
0

Ursprüngliche Antwort sagte, es in einen Iframe zu setzen. Die bessere Lösung besteht darin, die Ereignisse offsetX und offsetY auf einer Zeichenfläche zu verwenden, deren Auffüllung auf 0px festgelegt ist.

<html>
<body>
<script>

var main=document.createElement('canvas');
main.width="200";
main.height="300";
main.style="padding:0px;margin:30px;border:thick dashed red";
document.body.appendChild(main);

// adding event listener

main.addEventListener('mousemove',function(e){
    var ctx=e.target.getContext('2d');
    var c=Math.floor(Math.random()*0xFFFFFF);
    c=c.toString(16); for(;c.length<6;) c='0'+c;
    ctx.strokeStyle='#'+c;
    ctx.beginPath();
    ctx.arc(e.offsetX,e.offsetY,3,0,2*Math.PI);
    ctx.stroke();
    e.target.title=e.offsetX+' '+e.offsetY;
    });

// it worked! move mouse over window

</script>
</body>
</html>
Smertrios2007
quelle
0

Hier ist was ich habe.

    $(".some-class").click(function(e) {

    var posx = 0;
    var posy = 0;

    posx = e.pageX;
    posy = e.pageY;

    alert(posx);
    alert(posy);
});
Shmoo
quelle
0

Sie können getBoudingClientRect()das relativeübergeordnete Element verwenden.

document.addEventListener("mousemove", (e) => {
  let xCoord = e.clientX - e.target.getBoundingClientRect().left + e.offsetX
  let yCoord = e.clientY - e.target.getBoundingClientRect().top + e.offsetY
  console.log("xCoord", xCoord, "yCoord", yCoord)
})
BrieucKyo
quelle