Encontre a posição do mouse em relação ao elemento

244

Quero fazer um pequeno aplicativo de pintura usando tela. Então, preciso encontrar a posição do mouse na tela.

Ben Shelock
fonte
2
Solução completa: acko.net/blog/…
edA-qa mort-ora-y
3
Eu amo o quão curto, mas explica tudo o que este post é.
Dwjohnston
Este é realmente velho, mas eu só comecei um projeto GitHub que, entre outras coisas, faz exatamente o que você precisa: brainlessdeveloper.com/mouse-move-interaction-spot-js
Fausto NA

Respostas:

177

Para pessoas que usam JQuery:

Às vezes, quando você aninha elementos, um deles com o evento associado, pode ser confuso entender o que o navegador vê como pai. Aqui, você pode especificar qual pai.

Você toma a posição do mouse e subtrai-a da posição de deslocamento do elemento pai.

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

Se você estiver tentando obter a posição do mouse em uma página dentro de um painel de rolagem:

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

Ou a posição relativa à página:

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

Observe a seguinte otimização de desempenho:

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

Dessa maneira, o JQuery não precisa procurar #elementpor cada linha.

Atualizar

Há uma versão mais recente, somente para JavaScript, abaixo, de @anytimecoder abaixo, para navegadores que suportam getBoundingClientRect () .

sparkyspider
fonte
7
Funcionou para você @ben, gostaria de receber uma "Resposta correta" ou um comentário sobre o que ainda não está funcionando para você. Talvez eu possa ajudar mais.
sparkyspider
8
Deve evitar usar $ ('selector') em um manipulador de eventos, a menos que você queira um código muito lento. Pré-selecione seu elemento e use a referência pré-selecionada em seu manipulador. O mesmo para $ (window) faz isso uma vez e o armazena em cache.
Austin France
2
isso não é uma menção necessário: se você copiar colar o código acima, lembre-se de corrigir var y = (evt.pageY - $('#element').offset().left) + $(window).scrollTop();avar y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();
Raj Nathani
77
Como isso poderia ser a resposta, já que a pergunta não tem nada a ver com jQuery?
FlorianB 30/08/19
2
@Black, mas algumas pessoas perguntam coisas em javascript, em vez de jquery, porque o jquery pode não ser compatível em seus ambientes.
dbrree
307

Como não encontrei uma resposta sem jQuery que pudesse copiar / colar, eis a solução que usei:

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 do exemplo completo

anytimecoder
fonte
2
Você precisa arredondar o retângulo delimitador para garantir valores inteiros com esse método.
Jake Cobb
2
Nova edição deve corrigir a rolagem problemas (usando clientX / Y)
Erik Koopmans
6
Esta resposta deve ser votada. Obrigado anytimecoder e @ErikKoopmans.
Ivan Ivan
3
PSA: o comentário de @mpen é obsoleto; esse método funciona, mesmo em casos com rolagem. Consulte a versão atualizada do seu violino: jsfiddle.net/6wcsovp2
Xharlie
4
Obrigado! Uma observação: você precisa e.currentTarget, não o e.target. Caso contrário, os elementos filhos vão afetá-lo
Maxim Georgievskiy
60

A seguir, calcula a relação da posição do mouse com o elemento da tela:

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

Neste exemplo, thisrefere-se ao exampleelemento e eé o onmousemoveevento

LindaQ
fonte
83
Talvez seja eu, mas duas linhas de códigos que usam a palavra-chave "this" não têm contexto?
Deratrius
9
Definitivamente sem contexto. 'e' é o evento e 'this' é o elemento ao qual o evento está vinculado var example = document.getElementById('example'); example.onmousemove = function(e) { var X = e.pageX - this.offsetLeft; var Y = e.pageY - this.offsetTop; }
Nick Bisby 20/13
22
Isso não funciona se algum elemento descendente usar posicionamento relativo ou absoluto.
EdA-qa mort-ora-y
12
Você pode alternar thispara e.currentTarget, que fornecerá a posição em relação ao elemento ao qual você adicionou o ouvinte de evento.
Linus Unnebäck
2
Isso parece dar a posição relacionada à parte visível do elemento, não ao elemento inteiro. Existe uma maneira de acomodar isso se parte do elemento não puder ser vista na janela de visualização e houver barras de rolagem etc.?
frabjous
37

Não há resposta em javascript puro que retorne coordenadas relativas quando o elemento de referência estiver aninhado dentro de outros que possam estar com posicionamento absoluto. Aqui está uma solução para este cenário:

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
fonte
3
Eu não acho que ele leva em consideração htmlelemento de compensação
apieceofbart
3
Funciona muito bem com contêineres de rolagem, com apenas uma pequena alteração: substitua while(reference !== undefined)por while(reference). No Chrome, pelo menos, o offsetParent não acaba sendo undefined, mas null. Apenas verificar se referenceé verdade garantirá que funcione com ambos undefinede null.
Blex
Eu daria outro +1 se pudesse, por me informar que existe uma offsetParentpropriedade, o que acaba sendo muito útil também em outras situações!
FonzTech 12/03/19
Em geral, verificando contra indefinido é geralmente uma má idéia
Juan Mendes
Eu acho que você precisa subtrair scrollLefte scrollTopcompensar descendentes rolados.
Robert
20

Uma boa descrição da dificuldade desse problema pode ser encontrada aqui: http://www.quirksmode.org/js/events_properties.html#position

Usando a técnica descrita lá, você pode encontrar a posição do mouse no documento. Então você acabou de verificar para ver se ele está dentro da caixa delimitadora do seu elemento, onde pode encontrar chamando element.getBoundingClientRect()que irá retornar um objeto com as seguintes propriedades: { bottom, height, left, right, top, width }. A partir daí, é trivial descobrir se o mesmo aconteceu dentro do seu elemento ou não.

David W. Keith
fonte
1
Infelizmente, esta não se há qualquer tipo de rotação acontecendo
Eric
17

Tentei todas essas soluções e, devido à minha configuração especial com um contêiner transformado em matriz (biblioteca panzoom), nenhum funcionou. Isso retorna o valor correto, mesmo se ampliado e panorâmico:

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

Mas somente se não houver elementos filhos no caminho. Isso pode ser contornado, tornando-os 'invisíveis' para o evento, usando CSS:

.child {
   pointer-events: none;
}
Fabian von Ellerts
fonte
3
Esta é definitivamente a maneira de fazer isso em 2019. As outras respostas são todas carregadas com bagagem velha e suja.
Colin D
1
@ColinD obrigado! Esqueci de acrescentar que isso também funciona no IE11.
Fabian von Ellerts
Isso funcionou para mim. No entanto, desconfio que 1) Poucas votações positivas 2) respostas com classificação mais alta sejam muito mais complicadas e 3) não vejo desvantagens explicadas. Alguém conhece algum golpe de usar essa abordagem?
Mark E
1
@ MarkE Não há nada de suspeito nisso. É uma das muitas falhas do StackOverflow. As respostas que você vê na parte superior foram postadas muitos anos antes desta resposta aqui, e ganharam um tremendo impulso na votação. Depois que uma resposta ganha esse impulso, é muito difícil e raro vencê-lo.
Jack Giffin
9

Me deparei com essa pergunta, mas, para fazê-lo funcionar no meu caso (usando dragover em um elemento DOM (não sendo canvas no meu caso)), descobri que você só precisa usar offsetXe offsetYno evento dragover-mouse .

onDragOver(event){
 var x = event.offsetX;
 var y = event.offsetY;
}
John
fonte
2
isso funcionou muito bem para mim. por que ninguém votou nisso? Gostaria de saber se existem armadilhas. Se eu encontrar algum, eu informarei de volta!
robalo
7
event.offsetX é relativo ao elemento sobre o qual o ponteiro do mouse está atualmente, não ao elemento que tem o ouvinte de dragover anexado. Se você não tiver uma estrutura de elemento aninhada, tudo bem, mas se você tiver, isso não funcionará.
opSB
7

Marquei a resposta de Mark van Wyk com +1, pois ela me levou na direção certa, mas não a resolveu completamente para mim. Eu ainda tinha um deslocamento na pintura de elementos contidos em outro elemento.

A seguir resolvi isso para mim:

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

Em outras palavras - eu simplesmente empilhei todas as compensações de todos os elementos aninhados

Matt
fonte
+1 para você! Esta é a resposta que eu estava procurando. Eu tinha duas telas empilhadas umas sobre as outras e as coordenadas estavam todas erradas por causa das outras divs. Eu sabia que esse era o problema, mas não sabia a lógica / equação para compensá-lo. Você acabou de corrigir meu problema também! = D obrigado!
Partack
5

Nenhuma das respostas acima é satisfatória IMO, então aqui está o que eu 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 você precisar conhecer a atual posição de rolagem Y da página:

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

Para aqueles que desenvolvem sites regulares ou PWAs (Progressive Web Apps) para dispositivos móveis e / ou laptops / monitores com telas sensíveis ao toque, você chegou aqui porque pode estar acostumado a eventos de mouse e é novo na experiência às vezes dolorosa do Touch eventos ... yay!

Existem apenas três regras:

  1. Faça o mínimo possível durante mousemoveou touchmoveeventos.
  2. Faça o máximo possível durante mousedownou touchstarteventos.
  3. Cancele a propagação e impeça os padrões dos eventos de toque para impedir que os eventos do mouse também sejam acionados em dispositivos híbridos.

Escusado será dizer que as coisas são mais complicadas com os toucheventos porque podem haver mais de um e são mais flexíveis (complicadas) que os eventos do mouse. Eu só vou cobrir um único toque aqui. Sim, estou sendo preguiçoso, mas é o tipo de toque mais comum, então existe.

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.

Prefere usar o Vue.js ? Eu faço! Então seu HTML ficaria assim:

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

você pode obtê-lo

var element = document.getElementById(canvasId);
element.onmousemove = function(e) {
    var xCoor = e.clientX;
    var yCoor = e.clientY;
}
Rob Waminal
fonte
Isso funcionará no IE ou o IE ainda usará window.event em vez de passar o evento para o primeiro argumento do ouvinte? edit - Eu acho que o IE não tem o elemento de tela de qualquer maneira até a versão 9, mas isso ainda provavelmente deve apoiar IE por causa de coisas como excanvas ....
Dagg Nabbit
21
Isto lhe dará as coordenadas relativas à janela do navegador, ainda precisa descobrir se eles estão no elemento usando element.getBoundingClientRect ()
David W. Keith
obrigado por me informar sobre getBoundingClientRect !!!! Eu nunca percebi que havia uma coisa dessas!
Gershom
@ DavidW.Keith comentário realmente deve ser considerado a resposta correta!
Ulrik. S
3

Retirado deste tutorial , com correções feitas graças ao comentário principal:

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

Use em uma tela da seguinte maneira:

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

Percebo que estou um pouco atrasado, mas isso funciona com javascript PURE e ainda fornece as coordenadas do ponteiro dentro do elemento se o elemento for maior que a viewport e o usuário tiver rolado.

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

Como funciona.

A primeira coisa que fazemos é obter a localização do elemento HTML (a área de conteúdo) em relação à viewport atual. Se a página tiver barras de rolagem e estiver rolada, o número retornado pela getBoundingClientRect().lefttag html será negativo. Em seguida, usamos esse número para calcular a distância entre o elemento e a esquerda da área de conteúdo. Comelement_offset_x = element.getBoundingClientRect().left......;

Conhecendo a distância do elemento da área de conteúdo. event.clientXnos dá a distância do ponteiro da janela de visualização. É importante entender que a viewport e a área de conteúdo são duas entidades diferentes; a viewport pode se mover se a página for rolada. Portanto, o clientX retornará o mesmo número, mesmo que a página seja rolada.

Para compensar isso, precisamos adicionar a posição x do ponteiro (em relação à viewport), à posição x da viewport (em relação à área de conteúdo). A posição X da viewport é encontrada com window.pageXOffset.

FutureSci
fonte
1
Obrigado por ser o único respondedor a pensar em rolagem. Considere alterar sua resposta para adicionar o eixo y também.
Frabjous
3

Com base na solução do @ Spider, minha versão não JQuery é a seguinte:

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

Isso funciona tanto com rolagem quanto com zoom (nesse caso, às vezes, ele retorna flutuantes).

Letokteren
fonte
Gostaria de votar, mas não deveriam ser sinais de menos para as compensações da página? Ou isso, ou os parênteses em torno da segunda parte?
Chris Sunami apoia Monica
1

As coordenadas do mouse dentro de uma tela podem ser obtidas graças a event.offsetX e event.offsetY. Aqui está um pequeno trecho para provar meu argumento:

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
fonte
Ele não funciona se outra div está sobrepondo a tela, assim como @opsb disse
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

A HTMLElement.offsetLeftpropriedade somente leitura retorna o número de pixels que o canto superior esquerdo do elemento atual é deslocado para a esquerda dentro doHTMLElement.offsetParent nó.

Para elementos de bloco, offsetTop, offsetLeft, offsetWidth, e offsetHeightdescrevem a caixa fronteira de um elemento em relação ao offsetParent.

No entanto, para os elementos de nível em linha (tal como span) que pode envolver a partir de uma linha para a seguinte, offsetTope offsetLeftdescrevem as posições da primeira caixa da fronteira (uso Element.getClientRects()para obter a sua largura e altura), enquanto offsetWidthe offsetHeightdescrever as dimensões da caixa de fronteira delimitadora (use Element.getBoundingClientRect()para obter sua posição). Portanto, uma caixa com a esquerda, superior, largura e altura de offsetLeft, offsetTop, offsetWidthe offsetHeightnão será uma caixa delimitadora para um período com o texto envolvido.

HTMLElement.offsetTop

A HTMLElement.offsetToppropriedade somente leitura retorna a distância do elemento atual em relação à parte superior do offsetParentnó.

MouseEvent.pageX

A pageXpropriedade somente leitura retorna a coordenada X (horizontal) em pixels do evento em relação ao documento inteiro. Essa propriedade leva em consideração qualquer rolagem horizontal da página.

MouseEvent.pageY

A MouseEvent.pageYpropriedade somente leitura retorna a coordenada Y (vertical) em pixels do evento em relação ao documento inteiro. Essa propriedade leva em consideração qualquer rolagem vertical da página.

Para mais explicações, consulte a 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
fonte
Embora esse trecho de código possa resolver a questão, incluir uma explicação realmente ajuda a melhorar a qualidade da sua postagem. Lembre-se de que você está respondendo à pergunta dos leitores no futuro e essas pessoas podem não saber os motivos da sua sugestão de código.
Patrick Hund
Eu realmente espero que os leitores no futuro tenham uma API JS que calcule isso para eles. ;-) Esta é provavelmente a resposta mais simples, completa e independente. Comentar código auto-explicativo é apenas uma distração para o desperdício.
precisa saber é o seguinte
Eu segundo o pedido de explicação de @ PatrickHund. Eu não sou um especialista em CSS / JS e saber mais sobre as relações entre, por exemplo, pagee offsetseria muito útil para mim. Obrigado por considerar esta solicitação!
CXW
@cxw Ok, você é o 2º voto negativo agora (tinha 1 voto positivo) ... Eu adicionei uma explicação longa agora, é como 10x enquanto as 4 linhas de código. De nada, divirta-se lendo. Eu considerei seu pedido! : p
lama12345 14/17
1
@cxw Eu brinquei adicionando um elemento posicionado absoluto extra e forçando o próprio elemento da tela para fora da tela também, então tive que rolar para ele, como a esquerda / parte superior da tela 2000px. Não foi possível obter esse código.
Lama12345
1

Eu implementei uma outra solução que eu acho muito simples, então pensei em compartilhar com vocês.

Portanto, o problema para mim era que a div arrastada saltaria para 0,0 para o cursor do mouse. Então, eu precisava capturar a posição do mouse no div para ajustar a nova posição do div.

Eu li as divs PageX e PageY e defino a parte superior e esquerda de acordo com isso e, em seguida, para obter os valores para ajustar as coordenadas para manter o cursor na posição inicial na div, uso um ouvinte onDragStart e armazeno o e.nativeEvent .layerX e e.nativeEvent.layerY que somente no acionador inicial fornecem a posição do mouse na div arrastável.

Código de exemplo:

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

Espero que isso ajude alguém que passou pelos mesmos problemas pelos quais passei :)

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

isso funciona ok!

M9J_cfALt
fonte
0

Você precisa conhecer a estrutura da sua página, porque se sua tela é filha de uma div que, por sua vez, é filha de outra div ... então a história fica mais complicada. Aqui está o meu código para uma tela que está dentro de 2 níveis de 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);

});

Eli Mashiah
fonte
0

A resposta original disse para colocá-lo em um iframe. A melhor solução é usar os eventos offsetX e offsetY em uma tela com o preenchimento definido como 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>
Smertrios2007
fonte
0

Aqui está o que eu tenho.

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

    var posx = 0;
    var posy = 0;

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

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

Você pode usar getBoudingClientRect()o relativepai.

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
fonte