Öğeye göre fare konumunu bulma


244

Tuval kullanarak küçük bir resim uygulaması yapmak istiyorum. Bu yüzden farenin tuval üzerindeki konumunu bulmam gerekiyor.



3
Ne kadar kısa seviyorum, ama bu yazının her şeyi açıklıyor.
dwjohnston

Bu çok eski, ama yeni bir GitHub projesi başlattım, diğer şeylerin yanı sıra tam olarak ihtiyacınız olanı yapıyor: brainlessdeveloper.com/mouse-move-interaction-spot-js
Fausto NA

Yanıtlar:


177

JQuery kullanan kişiler için:

Bazen, bunlardan biri etkinliğe eklenmiş olan iç içe geçmiş öğeleriniz olduğunda, tarayıcınızın üst öğe olarak gördüklerini anlamak kafa karıştırıcı olabilir. Burada hangi ebeveyni belirtebilirsiniz.

Fare konumunu alır ve daha sonra üst öğenin ofset konumundan çıkarırsınız.

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

Fare konumunu kaydırma bölmesinin içindeki bir sayfada almaya çalışıyorsanız:

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

Veya sayfaya göre konum:

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

Aşağıdaki performans optimizasyonuna dikkat edin:

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

Bu şekilde, JQuery'nin #elementher satır için arama yapması gerekmez .

Güncelleme

GetBoundingClientRect () 'i destekleyen tarayıcılar için aşağıdaki @ anytimecoder tarafından daha yeni, yalnızca JavaScript içeren bir sürüm var .


7
@Ben sizin için işe yaradı mı, bir "Doğru Yanıt" veya sizin için hala çalışmayan şeyler hakkında bir yorum için teşekkür ederiz. Belki daha fazla yardım edebilirim.
sparkyspider

8
Çok yavaş kod istemiyorsanız, bir olay işleyicisinde $ ('selector') kullanmaktan kaçınmalısınız. Öğenizi önceden seçin ve işleyicinizde önceden seçilmiş referansı kullanın. Aynı şey $ (window) için bir kez yapın ve önbellekleyin.
Austin Fransa

2
Bu gerekli bir söz değildir: Yukarıdaki kodu yapıştırmadan kopya halinde, düzeltmeye hatırlamak var y = (evt.pageY - $('#element').offset().left) + $(window).scrollTop();içinvar y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();
Raj Nathani

77
Sorunun jQuery ile hiçbir ilgisi olmadığından, bu nasıl olabilir?
FlorianB

2
@Siyah ama bazı insanlar jquery yerine javascript'te bir şeyler soruyor çünkü jquery ortamlarında uyumlu olmayabilir.
dbrree

307

Kopyalayabildiğim / yapıştırabildiğim jQuery içermeyen bir cevap bulamadığım için, kullandığım çözüm:

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

Tam örnek JSFiddle


2
Bu yöntemle tamsayı değerlerini sağlamak için sınırlayıcı rektifi yuvarlamanız gerekir .
Jake Cobb

2
Yeni düzenleme kaydırma sorunlarını düzeltmelidir (clientX / Y kullanarak)
Erik Koopmans

6
Bu cevap oylanmalıdır. Her zaman teşekkürlercoder ve @ErikKoopmans.
Ivan

3
PSA: @mpen 'in yorumu eski; bu yöntem kaydırma durumunda bile çalışır. Onların Fiddle: jsfiddle.net/6wcsovp2
Xharlie

4
Teşekkür ederim! Bir not: e.currentTargete.target değil, ihtiyacınız var . Aksi takdirde, çocuk unsurları bunu etkileyecek
Maxim Georgievskiy

60

Aşağıdakiler, tuval öğesiyle fare konum ilişkisini hesaplar:

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

Bu örnekte, öğeye thisatıfta bulunur ve olaydır.exampleeonmousemove


83
Belki benim ama "bu" anahtar kelimesini kullanan iki kod satırı bağlamdan yoksun?
Deratrius

9
Kesinlikle bağlam eksik. 'e' olay ve 'bu' olayın bağlı olduğu unsurdur var example = document.getElementById('example'); example.onmousemove = function(e) { var X = e.pageX - this.offsetLeft; var Y = e.pageY - this.offsetTop; }
Nick Bisby

22
Bazı inen elemanlar göreceli veya mutlak konumlandırma kullanıyorsa bu çalışmaz.
edA-qa mort-ora-y

12
Dışarı geçiş yapabilirsiniz thisiçin e.currentTargetsize etkinlik dinleyici ekledi elemana konumunu alacak.
Linus Unnebäck

2
Bu , tüm öğeye değil, konumun öğenin görünür kısmına ilişkindir gibi görünmektedir . Öğenin bir kısmı görünüm alanında görülemiyorsa ve kaydırma çubukları vb. Varsa, bunu yapmanın bir yolu var mı?
Ocak'ta

37

Saf javascript'te, referans eleman mutlak konumlandırma ile olabilen diğerlerinin içine yerleştirildiğinde göreceli koordinatlar döndüren bir cevap yoktur. İşte bu senaryoya bir çözüm:

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
Ben htmlöğe ofset dikkate alır sanmıyorum
apieceofbart

3
Değiştirin: sadece biraz değişiklikle, kapların kaydırma ile harika çalışıyor while(reference !== undefined)ile while(reference). En azından Chrome'da, offsetParent olmakla kalmaz undefined, aynı zamanda null. Sadece doğru olup olmadığını kontrol etmek reference, hem undefinedve hem de ile çalışmasını sağlayacaktır null.
blex

offsetParentBaşka durumlarda çok yararlı olduğu ortaya çıkan bir mülk olduğunu bana bildirerek, yapabilseydim başka bir +1 verirdim !
FonzTech

Genel olarak, tanımsızlara karşı kontrol etmek genellikle kötü bir fikirdir
Juan Mendes

Bence kaydırılan torunları çıkarmanız scrollLeftve scrollToptelafi etmeniz gerekiyor .
Robert

20

Bu sorunun zorluğuna ilişkin iyi bir yazıyı burada bulabilirsiniz: http://www.quirksmode.org/js/events_properties.html#position

Burada açıklanan tekniği kullanarak farelerin konumunu belgedeki bulabilirsiniz. Sonra sadece size arayarak bulabilirsiniz elemanının sınırlayıcı kutunun içinde olup olmadığını kontrol edin element.getBoundingClientRect(): Aşağıdaki özelliklere sahip bir nesne döndürür { bottom, height, left, right, top, width }. Oradan bile elemanınızın içinde olup olmadığını anlamak önemsizdir.


1
Ne yazık ki, herhangi bir rotasyon oluyorsa başarısız olur
Eric

17

Tüm bu çözümleri denedim ve özel kurulum nedeniyle bir matris dönüştürülmüş konteyner (panzoom kütüphanesi) hiçbiri işe yaramadı. Bu, yakınlaştırılmış ve yatay kaydırılmış olsa bile doğru değeri döndürür:

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

Ama sadece yolda alt öğe yoksa. Bu, CSS kullanılarak etkinliğe 'görünmez' hale getirilerek atlatılabilir:

.child {
   pointer-events: none;
}

3
Bu kesinlikle 2019'da bunu yapmanın bir yoludur. Diğer cevapların hepsi eski kaba bagajlarla yüklenir.
Colin D

1
@ColinD teşekkür ederim! Bunun IE11'de de çalıştığını eklemeyi unuttum.
Fabian von Ellerts

Bu benim için çalıştı. Ancak, 1) Birkaç upvotes 2) daha yüksek puanlar çok daha karmaşık ve 3) hiçbir sakınca görmüyorum şüpheli. Bu yaklaşımı kullanmanın bir yolu var mı?
Mark E

1
@MarkE Bu konuda şüpheli bir şey yok. StackOverflow'un birçok hatasından biridir. En üstte gördüğünüz cevap, bu cevaptan yıllar önce yayınlanmıştır, bu yüzden muazzam bir yukarı oy ivme kazanmışlardır. Bir cevap bu ivme kazandığında, onu yenmek oldukça zor ve nadirdir.
Jack Giffin

9

Bu soru geldi, ama benim durum için çalışmasını sağlamak için (() benim durumumda tuval olmadığı DOM-elemana DragOver kullanarak), ben sadece kullanmak zorunda olduğunu tespit offsetXve offsetYdragover-fare olayı .

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

2
bu benim için harika çalıştı. neden kimse bunu iptal etmedi? Acaba herhangi bir tuzak var mı? Eğer bulursam rapor vereceğim!
levrek

7
event.offsetX, sürükleyici dinleyicisinin bağlı olduğu öğeye değil, fare işaretçisinin üzerinde olduğu öğeye göredir. Yuvalanmış bir öğe yapınız yoksa, bu iyi, ama eğer yaparsanız bu işe yaramaz.
opsb

7

Mark van Wyk'un cevabı beni doğru yöne götürdüğü için + 1'ledi, ama benim için tam olarak çözmedi. Hala başka bir elementin içindeki elementlerdeki resim üzerinde bir ofset vardı.

Aşağıdaki benim için çözdü:

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

Başka bir deyişle - ben sadece iç içe tüm unsurların ofset istif


+1 sizin için! Aradığım cevap bu. Üst üste iki tuval yığılmıştım ve diğer div'ler nedeniyle koordinatların hepsi yanlıştı. Sorunun bu olduğunu biliyordum, ama telafi etmek için mantık / denklemi bilmiyordum. Sen de benim sorunumu çözdün! = D teşekkürler!
Partack

5

Yukarıdaki cevapların hiçbiri tatmin edici IMO değildir, bu yüzden kullanıyorum:

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

Sayfanın geçerli Y kaydırma konumunu bilmeniz gerekirse:

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

4

Mobil cihazlar ve / veya dokunmatik ekranlı dizüstü bilgisayarlar / monitörler için normal web siteleri veya PWA'lar (Aşamalı Web Uygulamaları) geliştirenler için, fare olaylarına alışık olabileceğiniz ve bazen acı verici Touch deneyiminde yeni olabileceğiniz için buraya geldiniz olaylar ... yay!

Sadece 3 kural vardır:

  1. mousemoveVeya sırasında mümkün olduğunca az yapıntouchmove olaylar.
  2. mousedownVeya sırasında mümkün olduğunca çok şey yapıntouchstart olaylar.
  3. Yayılmayı iptal edin ve fare olaylarının karma aygıtlarda da tetiklenmesini önlemek için dokunma olayları için varsayılanları önleyin.

Söylemeye gerek yok, toucholaylar olaylarla daha karmaşıktır, çünkü birden fazla olabilir ve fare olaylarından daha esnek (karmaşık )dır. Burada sadece tek bir dokunuşu ele alacağım. Evet, tembelim, ama en yaygın dokunuş türü, bu yüzden orada.

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.

Vue.js kullanmayı tercih ediyor musunuz? Yaparım! Ardından HTML'niz şöyle görünür:

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

3

tarafından alabilirsiniz

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

Bu IE'de çalışır mı, yoksa olayı dinleyicinin ilk argümanına iletmek yerine IE hala window.event kullanıyor mu? edit - Sanırım IE 9 sürümüne kadar zaten tuval elemanı yok, ama bu
excanvas

21
Bu, tarayıcı penceresine göre koordinatları verecektir, yine de element.getBoundingClientRect () kullanarak öğede olup olmadıklarını anlamanız gerekir
David W. Keith

beni getBoundingClientRect hakkında bilgilendirdiğiniz için teşekkür ederiz !!!! Böyle bir şey olduğunu hiç fark etmemiştim!
Gershom

@ DavidW.Keith yorumu gerçekten doğru cevap olarak düşünülmelidir!
Ulrik. S

3

Alındığı Bu eğitimde üst yorumun sayesinde yapılan düzeltmelerle:

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

Bir tuval üzerinde aşağıdaki gibi kullanın:

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

3

Biraz geç kaldığımı anlıyorum, ancak bu PURE javascript ile çalışıyor ve öğe görünüm penceresinden daha büyükse ve kullanıcı kaydırdıysa, öğenin içindeki işaretçinin koordinatlarını bile veriyor.

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

Nasıl çalışır.

İlk yaptığımız şey HTML öğesinin (içerik alanı) geçerli görünüm penceresine göre konumunu almaktır. Sayfada kaydırma çubukları varsa ve kaydırılırsa, tarafından döndürülen sayıgetBoundingClientRect().left html etiketi için negatif olur. Daha sonra bu sayıyı, öğe ile içerik alanının solu arasındaki mesafeyi hesaplamak için kullanırız. İleelement_offset_x = element.getBoundingClientRect().left......;

Elemanın içerik alanından uzaklığını bilmek. event.clientXbize işaretçinin görünümden uzaklığını verir. Görünüm penceresinin ve içerik alanının iki farklı varlık olduğunu anlamak önemlidir, sayfa kaydırıldığında görünüm alanı hareket edebilir. Bu nedenle, sayfa kaydırılsa bile clientX AYNI numarayı döndürür.

Bunu telafi etmek için işaretçinin x konumunu (görünüm penceresine göre), görünüm penceresinin x konumuna (içerik alanına göre) eklememiz gerekir. Görünüm penceresinin X konumu şununla bulunur: window.pageXOffset.


1
Kaydırma hakkında düşünen tek yanıt verdiğin için teşekkürler. Y eksenini de eklemek için cevabınızı değiştirmeyi düşünün.
Ocak'ta

3

@ Spider'ın çözümüne dayanarak, benim JQuery olmayan sürümüm şudur:

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

Bu hem kaydırma hem de yakınlaştırma ile çalışır (bu durumda bazen yüzer döndürür).


Ben oy ediyorum, ama bu sayfa ofsetleri için eksi işaretleri olmamalı? Ya bu, ya da ikinci bölümün etrafındaki parantez?
Chris Sunami,

1

Bir tuval içindeki fare koordinatları event.offsetX ve event.offsetY sayesinde elde edilebilir. Demek istediğimi kanıtlamak için küçük bir pasaj:

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>
    


@Opsb'nin dediği gibi başka bir div tuvalin üstünü kaplıyorsa işe yaramaz
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

Salt HTMLElement.offsetLeftokunur özelliği, geçerli öğenin sol üst köşesinin,HTMLElement.offsetParent düğüm .

Blok düzeyi elemanlar için offsetTop, offsetLeft, offsetWidthve offsetHeightbir elemanın nisbetle sınır kutusunun tarif offsetParent.

Bununla birlikte, (örneğin, içi seviyesi elemanları için spanbir satır bir sonraki kaydırmak, olabilir) offsetTopve offsetLeft(kullanımı ilk sınır kutusunun konumlarını tanımlayan Element.getClientRects()genişliği ve yüksekliği elde etmek için), süre offsetWidthve offsetHeightsınırlayıcı sınır kutusunun boyutları tarif ( Element.getBoundingClientRect()konumunu almak için kullanın ). Bu nedenle sol üst, genişlik ve yüksekliğe sahip bir kutu offsetLeft, offsetTop, offsetWidthve offsetHeightsarılı metin ile bir zaman dilimi için bir sınırlama kutusu olmayacaktır.

HTMLElement.offsetTop

Salt HTMLElement.offsetTopokunur özelliği, geçerli öğenin offsetParentdüğümün tepesine göre uzaklığını döndürür .

MouseEvent.pageX

Salt pageXokunur özelliği, tüm belgeye göre olayın pikselleri olarak X (yatay) koordinatını döndürür. Bu özellik, sayfanın yatay kaydırılmasını dikkate alır.

MouseEvent.pageY

MouseEvent.pageY okunur özelliği, tüm belgeye göre olayın piksel cinsinden Y (dikey) koordinatını döndürür. Bu özellik, sayfanın dikey kaydırılmasını dikkate alır.

Daha fazla açıklama için lütfen Mozilla Geliştirici Ağı'na bakın:

https://developer.mozilla.org/tr-TR/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


Bu kod snippet'i soruyu çözebilir, ancak bir açıklama da dahil olmak üzere , yayınınızın kalitesini artırmaya yardımcı olur. Gelecekte okuyucular için soruyu cevapladığınızı ve bu kişilerin kod önerinizin nedenlerini bilmeyebileceğini unutmayın.
Patrick Hund

Umarım gelecekte okuyucuların bunu hesaplayan bir JS API'si vardır. ;-) Bu muhtemelen en basit, tam, kendi kendine yeten cevaptır. Kendini açıklayan kodun yorumlanması sadece dikkat dağıtıcıdır.
lama12345

PatrickHund'un açıklama talebini @ ikinci olarak söyledim. Ben bir CSS / JS uzmanı değilim, örneğin arasındaki ilişkiler hakkında daha fazla bilgi sahibi olmak pageve offsetbana çok yardımcı olacaktır. Bu isteği düşündüğünüz için teşekkür ederiz!
cxw

@cxw Tamam, şimdi 2. downvote sensin (1 yukarı oy aldım) ... Şimdi uzun bir açıklama ekledim, 4 satır kod kadar 10x gibi. Bir şey değil, iyi eğlenceler. Talebinizi düşündüm! : p
lama12345

1
@cxw Ekstra mutlak konumlandırılmış bir eleman ekleyerek ve tuval elemanının kendisini de ekranın dışına zorlayarak dağıttım, bu yüzden sol / üst 2000 piksel ekran gibi kaydırmak zorunda kaldım. Bu kod kırılamadı.
lama12345

1

Çok basit olduğunu düşündüğüm başka bir çözüm uyguladım, bu yüzden sizinle paylaşacağımı düşündüm.

Benim için sorun, sürüklenen div'ın fare imleci için 0,0'a atlamasıydı . Bu yüzden div yeni konumunu ayarlamak için div fareler konumunu yakalamak gerekiyordu.

PageX ve PageY divlerini okudum ve buna göre üst ve solu ayarladım ve sonra imleci div'da ilk konumda tutmak için koordinatları ayarlamak için değerleri almak için bir onDragStart dinleyicisi kullanıyorum ve e.nativeEvent'i saklıyorum .layerX ve e.nativeEvent.layerY sadece ilk tetikleyicide size sürüklenebilir div içindeki farelerin konumunu verir.

Örnek kod:

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

Umarım bu yaşadığım aynı problemleri yaşayan birine yardımcı olur :)


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

bu iyi çalışıyor!


0

Sayfanızın yapısını bilmelisiniz, çünkü eğer tuvaliniz bir div'ın çocuğu ise, bu da başka bir div'ın çocuğuysa ... hikaye daha karmaşık hale gelir. İşte div s 2 seviyeleri içinde bir tuval için benim kod:

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

Orijinal cevap bir iframe koymak söyledi. Daha iyi çözüm, dolgu 0px olarak ayarlanmış bir tuval üzerinde offsetX ve offsetY olaylarını kullanmaktır.

<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

İşte sahip olduğum şey.

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

    var posx = 0;
    var posy = 0;

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

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

0

Sen kullanabilirsiniz getBoudingClientRect()ait relativeebeveyn.

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)
})
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.