Trova la posizione del mouse rispetto all'elemento


244

Voglio creare una piccola app di pittura usando la tela. Quindi ho bisogno di trovare la posizione del mouse sulla tela.


2
Soluzione completa: acko.net/blog/…
edA-qa mort-ora-y

3
Adoro quanto breve, ma spiega tutto questo post.
dwjohnston,

Questo è davvero vecchio, ma ho appena iniziato un progetto GitHub che, tra le altre cose, fa esattamente ciò di cui hai bisogno: brainlessdeveloper.com/mouse-move-interaction-spot-js
Fausto NA

Risposte:


177

Per le persone che usano JQuery:

A volte, quando hai elementi nidificati, uno dei quali con l'evento associato, può essere fonte di confusione capire cosa vede il tuo browser come genitore. Qui puoi specificare quale genitore.

Prendi la posizione del mouse e quindi la sottrai dalla posizione di offset dell'elemento genitore.

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

Se stai cercando di ottenere la posizione del mouse su una pagina all'interno di un riquadro di scorrimento:

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

O la posizione relativa alla pagina:

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

Nota la seguente ottimizzazione delle prestazioni:

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

In questo modo, JQuery non deve cercare #elementogni riga.

Aggiornare

Di seguito è disponibile una versione più recente, solo JavaScript, di @anytimecoder per i browser che supportano getBoundingClientRect () .


7
Ha funzionato per te @ben, apprezzerei una "risposta corretta" o un commento su ciò che ancora non funziona per te. Forse posso aiutare ulteriormente.
sparkyspider,

8
Dovresti evitare di usare $ ('selettore') in un gestore di eventi, a meno che tu non voglia un codice molto lento. Preseleziona il tuo elemento e usa il riferimento preselezionato nel tuo gestore. Lo stesso per $ (finestra), fallo una volta e memorizzalo nella cache.
Austin, Francia,

2
questa non è una menzione necessaria: se state copiate incollando il codice di cui sopra, ricordarsi di correggere var y = (evt.pageY - $('#element').offset().left) + $(window).scrollTop();avar y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();
Raj Nathani

77
Come potrebbe essere la risposta, dato che la domanda non ha nulla a che fare con jQuery?
FlorianB,

2
@Nero, ma alcune persone chiedono cose in javascript invece di jquery perché jquery potrebbe non essere compatibile nei loro ambienti.
dbrree

307

Dato che non ho trovato una risposta priva di jQuery che potrei copiare / incollare, ecco la soluzione che ho usato:

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 di esempio completo


2
È necessario arrotondare il rettangolo di limitazione per garantire valori interi con questo metodo.
Jake Cobb,

2
La nuova modifica dovrebbe risolvere i problemi di scorrimento (utilizzando clientX / Y)
Erik Koopmans,

6
Questa risposta dovrebbe essere votata. Grazie anytimecoder e @ErikKoopmans.
Ivan

3
PSA: il commento di @mpen è obsoleto; questo metodo FUNZIONA, anche nei casi con scorrimento. Guarda la versione aggiornata del loro violino: jsfiddle.net/6wcsovp2
Xharlie

4
Grazie! Una nota: è necessario e.currentTarget, non e.target. Altrimenti, gli elementi dei bambini lo influenzeranno
Maxim Georgievskiy,

60

Quanto segue calcola la posizione del mouse in relazione all'elemento canvas:

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

In questo esempio, thisfa riferimento exampleall'elemento ed eè l' onmousemoveevento.


83
Forse sono io ma due righe di codice che usano la parola chiave "this" mancano di contesto?
Deratrius,

9
Decisamente privo di contesto. 'e' è l'evento e 'questo' è l'elemento a cui è legato l'evento var example = document.getElementById('example'); example.onmousemove = function(e) { var X = e.pageX - this.offsetLeft; var Y = e.pageY - this.offsetTop; }
Nick Bisby,

22
Questo non funziona se un elemento discendente utilizza un posizionamento relativo o assoluto.
edA-qa mort-ora-y,

12
Puoi passare thisa e.currentTarget, che ti porterà la posizione relativa all'elemento a cui hai aggiunto il listener di eventi.
Linus Unnebäck,

2
Questo sembra dare la posizione relativa alla parte visibile dell'elemento, non all'intero elemento. C'è un modo per adattarsi a questo se una parte dell'elemento non può essere vista nella finestra e ci sono barre di scorrimento, ecc.?
frabjous

37

Non esiste una risposta in javascript puro che restituisce coordinate relative quando l'elemento di riferimento è nidificato all'interno di altri che possono essere con posizionamento assoluto. Ecco una soluzione a questo scenario:

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

}

3
Non penso che tenga conto htmldell'offset degli elementi
apieceofbart il

3
Funziona alla grande con i contenitori scorrevoli, con solo una piccola modifica: sostituisci while(reference !== undefined)con while(reference). Almeno in Chrome, offsetParent non finisce per essere undefined, ma null. Basta verificare se referenceè vero assicurerà che funzioni con entrambi undefinede null.
Blex,

Darei un altro +1 se potessi, per farmi sapere che esiste una offsetParentproprietà, che risulta essere molto utile anche in altre situazioni!
FonzTech,

In generale, controllare contro undefined è di solito una cattiva idea
Juan Mendes,

Penso che sia necessario sottrarre scrollLefte scrollTopcompensare i discendenti scorrevoli.
Robert,

20

Un buon resoconto della difficoltà di questo problema può essere trovato qui: http://www.quirksmode.org/js/events_properties.html#position

Utilizzando la tecnica qui descritta è possibile trovare la posizione dei mouse nel documento. Poi basta controllare per vedere se è all'interno del riquadro di delimitazione del vostro elemento, che si possono trovare chiamando element.getBoundingClientRect()che restituirà un oggetto con le seguenti proprietà: { bottom, height, left, right, top, width }. Da lì è banale capire se è successo persino all'interno del tuo elemento.


1
Purtroppo, questo fallisce se c'è qualche tipo di rotazione in corso
Eric

17

Ho provato tutte queste soluzioni e grazie alla mia configurazione speciale con un contenitore trasformato a matrice (libreria panzoom) nessuna ha funzionato. Ciò restituisce il valore corretto, anche se ingrandito e spostato:

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

Ma solo se non ci sono elementi figlio sulla strada. Questo può essere eluso rendendoli "invisibili" all'evento, usando CSS:

.child {
   pointer-events: none;
}

3
Questo è sicuramente il modo di farlo nel 2019. Le altre risposte sono tutte caricate con il vecchio bagaglio croccante.
Colin D

1
@ColinD grazie! Ho dimenticato di aggiungere che funziona anche in IE11.
Fabian von Ellerts,

Questo ha funzionato per me. Tuttavia, ho il sospetto che 1) Pochi voti 2) Le risposte più votate sono molto più complicate e 3) Non vedo alcun inconveniente spiegato. Qualcuno sa qualche truffa sull'uso di questo approccio?
Segna E

1
@MarkE Non c'è nulla di sospetto al riguardo. È uno dei tanti difetti di StackOverflow. Quelle risposte che vedi in alto sono state pubblicate molti anni prima di questa risposta qui, quindi hanno ottenuto un enorme slancio di votazione. Una volta che una risposta ottiene questo slancio, è piuttosto difficile e abbastanza raro batterlo.
Jack Giffin il

9

Mi sono imbattuto in questa domanda, ma per farlo funzionare nel mio caso (usando dragover su un elemento DOM (non essere canvas nel mio caso)), ho scoperto che devi solo usare offsetXe offsetYsull'evento dragover-mouse .

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

2
questo ha funzionato benissimo per me. perché nessuno lo ha votato? Mi chiedo se ci siano insidie. Se ne trovo qualcuno, riporterò indietro!
spigola

7
event.offsetX è relativo all'elemento su cui si trova attualmente il puntatore del mouse, non all'elemento a cui è collegato l'ascoltatore dragover. Se non hai una struttura di elementi nidificati, allora va bene, ma se lo fai non funzionerà.
opsb,

7

Ho fatto +1 sulla risposta di Mark van Wyk perché mi ha portato nella giusta direzione, ma non mi ha risolto del tutto. Avevo ancora un offset sulla pittura in elementi contenuti in un altro elemento.

Il superficiale mi ha risolto:

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

In altre parole, ho semplicemente impilato tutti gli offset da tutti gli elementi nidificati


+1 per te! Questa è la risposta che stavo cercando. Avevo due tele sovrapposte l'una sull'altra e le coordinate erano tutte sbagliate a causa degli altri div. Sapevo che questo era il problema, ma non conoscevo la logica / equazione per compensarlo. Hai appena risolto anche il mio problema! = D grazie!
Partack,

5

Nessuna delle risposte sopra è IMO soddisfacente, quindi ecco cosa uso:

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

E se hai mai bisogno di conoscere l'attuale posizione di scorrimento Y della pagina:

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

4

Per quelli di voi che sviluppano normali siti Web o PWA (Progressive Web App) per dispositivi mobili e / o laptop / monitor con touchscreen, siete arrivati ​​qui perché potreste essere abituati agli eventi del mouse e non conoscete l'esperienza a volte dolorosa di Touch eventi ... yay!

Ci sono solo 3 regole:

  1. Fai il meno possibile durante mousemoveo touchmoveeventi.
  2. Fai il più possibile durante mousedowno touchstarteventi.
  3. Annullare la propagazione e prevenire le impostazioni predefinite per gli eventi touch per impedire che gli eventi del mouse vengano attivati ​​anche su dispositivi ibridi.

Inutile dire che le cose sono più complicate con gli toucheventi perché possono essercene più di una e sono più flessibili (complicate) degli eventi del mouse. Tratterò solo un singolo tocco qui. Sì, sono pigro, ma è il tipo di tocco più comune, quindi lì.

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.

Preferisci usare Vue.js ? Lo voglio! Quindi il tuo HTML sarebbe simile al seguente:

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

3

puoi farcela

var element = document.getElementById(canvasId);
element.onmousemove = function(e) {
    var xCoor = e.clientX;
    var yCoor = e.clientY;
}

Funzionerà in IE o IE utilizza ancora window.event invece di passare l'evento al primo argomento dell'ascoltatore? modifica - Immagino che IE manchi comunque dell'elemento canvas fino alla versione 9, ma questo dovrebbe probabilmente supportare IE a causa di cose come excanvas ....
Dagg Nabbit

21
Ciò fornirà le coordinate relative alla finestra del browser, è ancora necessario capire se si trovano nell'elemento usando element.getBoundingClientRect ()
David W. Keith

grazie per avermi informato di getBoundingClientRect !!!! Non ho mai capito che esistesse una cosa del genere!
Gershom il

@ DavidW.Keith comment dovrebbe davvero essere considerata la risposta corretta!
Ulrik. S

3

Tratto da questo tutorial , con correzioni apportate grazie al commento in alto:

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

Utilizzare su una tela come segue:

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

3

Mi rendo conto di essere un po 'in ritardo, ma funziona con PURE javascript e ti dà persino le coordinate del puntatore all'interno dell'elemento se l'elemento è più grande del viewport e l'utente ha fatto scorrere.

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

Come funziona.

La prima cosa che facciamo è ottenere la posizione dell'elemento HTML (l'area del contenuto) rispetto alla finestra corrente. Se la pagina ha barre di scorrimento ed è fatta scorrere, il numero restituito getBoundingClientRect().leftper il tag html sarà negativo. Quindi usiamo questo numero per calcolare la distanza tra l'elemento e la sinistra dell'area del contenuto. Conelement_offset_x = element.getBoundingClientRect().left......;

Conoscere la distanza dell'elemento dall'area del contenuto. event.clientXci dà la distanza del puntatore dal viewport. È importante comprendere che il viewport e l'area del contenuto sono due entità diverse, il viewport può spostarsi se si scorre la pagina. Quindi, clientX restituirà il numero SAME anche se la pagina viene fatta scorrere.

Per compensare ciò, è necessario aggiungere la posizione x del puntatore (relativa alla finestra), alla posizione x della finestra (relativa all'area del contenuto). La posizione X della finestra viene trovata con window.pageXOffset.


1
Grazie per essere l'unico risponditore a pensare allo scorrimento. Valuta di modificare la risposta per aggiungere anche l'asse y.
frabjous

3

Basato sulla soluzione di @ Spider, la mia versione non JQuery è questa:

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

Funziona sia con lo scorrimento che con lo zoom (nel qual caso a volte restituisce float).


Vorrei votare, ma non dovrebbero essere segni meno per gli offset di pagina? O quello o le parentesi attorno alla seconda parte?
Chris Sunami supporta Monica il

1

Le coordinate del mouse all'interno di un'area di disegno possono essere ottenute grazie a event.offsetX e event.offsetY. Ecco un piccolo frammento per dimostrare il mio punto:

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>
    


Non funziona se un altro div sta sovrapponendo la tela, proprio come ha detto @opsb
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

La HTMLElement.offsetLeftproprietà di sola lettura restituisce il numero di pixel che l'angolo superiore sinistro dell'elemento corrente è spostato a sinistra all'interno diHTMLElement.offsetParent nodo.

Per elementi di blocco, offsetTop,offsetLeft , offsetWidth, e offsetHeightdescrivere il bordo casella di un elemento rispetto al offsetParent.

Tuttavia, per gli elementi a livello di linea (come span) che possono avvolgere da una linea alla successiva offsetTope offsetLeftdescrivere le posizioni della prima casella del bordo (usare Element.getClientRects()per ottenere la sua larghezza e altezza), mentre offsetWidthe offsetHeightdescrivere le dimensioni della casella del bordo delimitante (usare Element.getBoundingClientRect()per ottenere la sua posizione). Pertanto, una casella con sinistra, superiore, larghezza e altezza di offsetLeft,offsetTop , offsetWidtheoffsetHeight non sarà un rettangolo di selezione per un arco con testo avvolto.

HTMLElement.offsetTop

La HTMLElement.offsetTopproprietà di sola lettura restituisce la distanza dell'elemento corrente rispetto alla parte superiore dioffsetParent nodo.

MouseEvent.pageX

Il pageX proprietà di sola lettura restituisce la coordinata X (orizzontale) in pixel dell'evento rispetto all'intero documento. Questa proprietà tiene conto di qualsiasi scorrimento orizzontale della pagina.

MouseEvent.pageY

Il MouseEvent.pageY proprietà di sola lettura restituisce la coordinata Y (verticale) in pixel dell'evento rispetto all'intero documento. Questa proprietà tiene conto di qualsiasi scorrimento verticale della pagina.

Per ulteriori spiegazioni, consultare la rete di sviluppatori Mozilla:

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


Sebbene questo frammento di codice possa risolvere la domanda, inclusa una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro e quelle persone potrebbero non conoscere i motivi del tuo suggerimento sul codice.
Patrick Hund,

Spero davvero che i lettori in futuro dispongano di un'API JS che calcoli questo per loro. ;-) Questa è probabilmente la risposta più semplice, completa e autonoma. Commentare il codice autoesplicativo è solo fonte di distrazione per i rifiuti.
lama12345,

Secondo la richiesta di @ PatrickHund per una spiegazione. Non sono un esperto CSS / JS e conoscere meglio le relazioni tra, ad esempio, pagee offsetsarebbe molto utile per me. Grazie per aver preso in considerazione questa richiesta!
Cxw,

@cxw Ok, ora sei il secondo downvote (aveva 1 upvote) ... Ho aggiunto una lunga spiegazione ora, è come 10x fino a quando le 4 righe di codice. Prego, buona lettura. Ho considerato la tua richiesta! : p
lama12345,

1
@cxw Ho fatto un casino aggiungendo un ulteriore elemento posizionato assoluto e forzando anche l'elemento canvas stesso fuori dallo schermo, quindi ho dovuto scorrere fino ad esso, come lo schermo sinistro / superiore 2000px. Impossibile ottenere la rottura di questo codice.
lama12345,

1

Ho implementato un'altra soluzione che penso sia molto semplice, quindi ho pensato di condividere con voi ragazzi.

Quindi, il problema per me era che il div trascinato saltava a 0,0 per il cursore del mouse. Quindi ho dovuto catturare la posizione dei mouse sul div per regolare la nuova posizione dei div.

Ho letto i div PageX e PageY e ho impostato la parte superiore e sinistra del secondo e quindi per ottenere i valori per regolare le coordinate per mantenere il cursore nella posizione iniziale nel div Uso un listener onDragStart e memorizzo e.nativeEvent .layerX ed e.nativeEvent.layerY che solo nel trigger iniziale ti dà la posizione dei topi all'interno del div trascinabile.

Codice di esempio:

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

Spero che questo possa aiutare qualcuno che ha attraversato gli stessi problemi che ho attraversato :)


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

funziona bene!


0

Devi conoscere la struttura della tua pagina, perché se la tua tela è figlia di un div che a sua volta è figlia di un altro div ... allora la storia diventa più complicata. Ecco il mio codice per una tela che si trova all'interno di 2 livelli di div s:

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

});


0

La risposta originale diceva di inserirla in un iframe. La soluzione migliore è utilizzare gli eventi offsetX e offsetY su una tela con il padding impostato su 0px.

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

0

Ecco cosa ho ottenuto.

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

    var posx = 0;
    var posy = 0;

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

    alert(posx);
    alert(posy);
});

0

Puoi usare getBoudingClientRect()il relativegenitore.

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)
})
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.