408 Stimmen

Mausposition relativ zum Element finden

Ich möchte eine kleine Mal-App mit Canvas erstellen. Ich muss also die Position der Maus auf der Leinwand finden.

22voto

David W. Keith Punkte 2226

Ein guter Bericht über die Schwierigkeit dieses Problems findet sich hier: http://www.quirksmode.org/js/events_properties.html#position

Mit der dort beschriebenen Technik können Sie die Position der Maus im Dokument ermitteln. Dann müssen Sie nur noch prüfen, ob sie sich innerhalb des Begrenzungsrahmens Ihres Elements befindet, was Sie durch den Aufruf von element.getBoundingClientRect() die ein Objekt mit den folgenden Eigenschaften zurückgibt: { bottom, height, left, right, top, width } . Von dort aus ist es trivial, herauszufinden, ob das Ereignis innerhalb Ihres Elements stattgefunden hat oder nicht.

11voto

Kohill Yang Punkte 101

Wenn Sie die LayerX und LayerY in Bezug auf ein Element erhalten möchten, können Sie vielleicht versuchen

let bbox_rect = document.getElementById("dom-ID").getBoundingClientRect()
let layerX = e.clientX-bbox_rect.left
let layerY = e.clientY-bbox_rect.top

11voto

John Punkte 8281

Ich stieß auf diese Frage, aber um es für meinen Fall zu machen (mit Dragover auf einem DOM-Element (nicht Leinwand in meinem Fall)), fand ich, dass Sie nur haben, um zu verwenden offsetX y offsetY auf das Dragover-Maus-Ereignis.

onDragOver(event){
 var x = event.offsetX;
 var y = event.offsetY;
}

9voto

Matt Punkte 268

Die Antwort von Mark van Wyk hat mich zwar in die richtige Richtung geführt, aber das Problem nicht ganz gelöst. Ich hatte immer noch einen Versatz beim Malen von Elementen, die in einem anderen Element enthalten waren.

Folgendes hat das Problem für mich gelöst:

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

Mit anderen Worten - ich habe einfach alle Offsets von allen verschachtelten Elementen gestapelt

7voto

John T. Punkte 321

Diejenigen unter Ihnen, die normale Websites oder PWAs (Progressive Web Apps) für mobile Geräte und/oder Laptops/Monitore mit Touchscreens entwickeln, sind hier gelandet, weil sie vielleicht an Mausereignisse gewöhnt sind und die manchmal schmerzhafte Erfahrung von Touch-Ereignissen neu ist... juhu!

Es gibt nur 3 Regeln:

  1. Tun Sie so wenig wie möglich während mousemove o touchmove Veranstaltungen.
  2. Tun Sie so viel wie möglich während mousedown o touchstart Veranstaltungen.
  3. Abbrechen der Weitergabe und Verhindern von Standardwerten für Berührungsereignisse, um zu verhindern, dass Mausereignisse auch auf Hybridgeräten ausgelöst werden.

Unnötig zu erwähnen, dass die Dinge komplizierter sind mit touch Ereignisse, weil es mehr als eines 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, so dort.

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.

Bevorzugt verwenden Vue.js ? Ich schon! Dann würde Ihr HTML folgendermaßen aussehen:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X