jQuery bir öğe içinde fare konumunu almak


165

Bir kullanıcının bir div içinde tıklayabileceği, daha sonra fareyi sürükleyebileceği ve daha sonra bir şeyin ne kadar olmasını istediklerini belirtmek için fareyi bırakabileceği bir kontrol yapmayı umuyordum. (Bu bir takvim kontrolü içindir, bu nedenle kullanıcı belirli bir etkinliğin süresini, zaman içinde gösterecektir)

Bunu yapmanın en iyi yolu, "div" üzerine bir "mouseup" olayı tetiklenene kadar div üzerinde bir "mousemove" olayı kaydeden bir "mousedown" olayı kaydetmek olacaktır. "Mousedown" ve "mouseup" olayları zaman aralığının başlangıcını ve sonunu tanımlar ve "fareyi kaldır" olaylarını takip ettiğimde, kullanıcının ne yaptığını görebilmesi için aralığın boyutunu dinamik olarak değiştirebilirim. Bunu Google Takvim'de etkinliklerin nasıl oluşturulduğuna dayandırdım.

Ben yaşıyorum sorun jQuery olay sadece tüm sayfaya referans olarak güvenilir fare koordinat bilgileri sağlamak gibi görünüyor. Üst öğeye ilişkin koordinatların ne olduğunu ayırt etmenin bir yolu var mı?

Düzenle:

Heres yapmaya çalıştığım şeyin bir resmi: alternatif metin

Yanıtlar:


305

Bunun bir yolu, olaydan ve koordinatlarını üst öğeye göre fare konumuna offsetçevirmek için jQuery yöntemini kullanmaktır . Gelecekte referans olması için bir örnek:event.pageXevent.pageY

$("#something").click(function(e){
   var parentOffset = $(this).parent().offset(); 
   //or $(this).offset(); if you really just want the current element's offset
   var relX = e.pageX - parentOffset.left;
   var relY = e.pageY - parentOffset.top;
});

2
Evet, üst öğenin düzeni değiştirilemiyorsa / değiştirilmiyorsa bu harika bir fikirdir!
Sivri

2
Bu cevap dolgu / sınırları dikkate alıyor mu?
LeeGee

10
Dokümanlara göre ofset , "gövde öğesinde ayarlanan kenarlıklar, kenar boşlukları veya dolguları" dikkate almaz. Kullanımdaki yayınlanan yanıtımla ilgili bir sorunla karşılaşmadım, ancak ayarlananları kontrol etmek iyi olabilir.
jball

2
Bunun çalışması gerekmiyor. offset()göreceli olarak göreli olduğundan, üst öğe başka bir öğenin alt öğesiyse bu yanlış sonuç verir. kullanımposition()Bunun yerine .
Flash Thunder

1
@FlashThunder ofset () göreceli değil, en azından dokümanlara göre değil. Ayrıca, gövde elemanı üzerinde herhangi bir kenar boşluğu veya dolgu bulunmaması standart bir uygulama olmalıdır.
James Watkins

18

Geçerli tıklanan öğeye göre tıklama konumunu almak için
Bu kodu kullanın

$("#specialElement").click(function(e){
    var x = e.pageX - this.offsetLeft;
    var y = e.pageY - this.offsetTop;
}); 

2
Cevabınız BTW'ye yardımcı oldu, kabul edilen cevap olmadı. Teşekkürler :) Bunun yerine aslında kullandığım şey: var y = e.pageY - $(this).offset().top;Ama cevabın beni doğru yola yönlendirdi.
Solomon Closson

11

Bu kod parçasını kullanıyorum, oldukça güzel :)

    <script language="javascript" src="http://code.jquery.com/jquery-1.4.1.js" type="text/javascript"></script>
<script language="javascript">
$(document).ready(function(){
    $(".div_container").mousemove(function(e){
        var parentOffset = $(this).parent().offset();
        var relativeXPosition = (e.pageX - parentOffset.left); //offset -> method allows you to retrieve the current position of an element 'relative' to the document
        var relativeYPosition = (e.pageY - parentOffset.top);
        $("#header2").html("<p><strong>X-Position: </strong>"+relativeXPosition+" | <strong>Y-Position: </strong>"+relativeYPosition+"</p>")
    }).mouseout(function(){
        $("#header2").html("<p><strong>X-Position: </strong>"+relativeXPosition+" | <strong>Y-Position: </strong>"+relativeYPosition+"</p>")
    });
});
</script>

9

@AbdulRahim yanıtı neredeyse doğrudur. Ama ben aşağıdaki işlevi yerine önermek (daha fazla referans için):

function getXY(evt, element) {
                var rect = element.getBoundingClientRect();
                var scrollTop = document.documentElement.scrollTop?
                                document.documentElement.scrollTop:document.body.scrollTop;
                var scrollLeft = document.documentElement.scrollLeft?                   
                                document.documentElement.scrollLeft:document.body.scrollLeft;
                var elementLeft = rect.left+scrollLeft;  
                var elementTop = rect.top+scrollTop;

                x = evt.pageX-elementLeft;
                y = evt.pageY-elementTop;

                return {x:x, y:y};
            }




            $('#main-canvas').mousemove(function(e){
                var m=getXY(e, this);
                console.log(m.x, m.y);
            });

1
Parlak iyileşme, günümü kurtardı.
Bud Damyanov

neredeyse, tuvale kenar boşluğu ekleyin ve kenar boşluğuna
kapıldınız

Bu harika bir kod parçası, çok teşekkür ederim!
Stefan

7

Bu çözüm, IE dahil tüm büyük tarayıcıları destekler. Ayrıca kaydırma ile ilgilenir. İlk olarak, özyinelemeli bir işlev kullanmadan öğenin sayfaya göre konumunu verimli bir şekilde alır. Daha sonra sayfaya göre fare tıklamasının x ve y değerlerini alır ve öğeye göre konum olan cevabı almak için çıkartma yapar (öğe örneğin bir görüntü veya div olabilir):

function getXY(evt) {
    var element = document.getElementById('elementId');  //replace elementId with your element's Id.
    var rect = element.getBoundingClientRect();
    var scrollTop = document.documentElement.scrollTop?
                    document.documentElement.scrollTop:document.body.scrollTop;
    var scrollLeft = document.documentElement.scrollLeft?                   
                    document.documentElement.scrollLeft:document.body.scrollLeft;
    var elementLeft = rect.left+scrollLeft;  
    var elementTop = rect.top+scrollTop;

        if (document.all){ //detects using IE   
            x = event.clientX+scrollLeft-elementLeft; //event not evt because of IE
            y = event.clientY+scrollTop-elementTop;
        }
        else{
            x = evt.pageX-elementLeft;
            y = evt.pageY-elementTop;
    }

3

Üst öğenizi "position: relative" yaparsanız, fare olaylarını izlediğiniz şeyler için "offset parent" olur. Böylece jQuery "position ()" buna göreli olacaktır.


Hey Pointy, cevabınız için teşekkürler. İfadenize dayanarak, önerdiğiniz şeyin jball'un önerdiğinden farklı olduğu anlaşılıyor, ancak nasıl olduğunu anlayamıyorum, ayrıntılandırabilir misiniz? Tekrar teşekkürler
Chris Dutrow

@DutrowLLC, Pointy, üst öğenin stilini değiştirmeyi öneriyor "position:relative". JQuery konumu daha sonra konumlarını sayfaya değil üst öğeye göre raporlar. Cevabımdaki ifade zayıf, bunun doğrudan Pointy'nin çözümü ile ilgili olduğu anlamına geliyor, ancak üst öğenin stil niteliklerine bağlı kalamayacağınız veya istemediğinizde ofseti hesaplamanın bir yoludur.
jball

Yani "position: relative" ayarını yaparsam jQuery, tüm tarayıcılarda relatiove konumunu doğru bir şekilde rapor eder mi? Sormamın nedeni, jQuery belgelerinin tüm tarayıcılardaki tek güvenilir fare konumunun tarayıcı penceresinin kendisiyle ilişkili olduğu anlamına geldiği için görünüyordu.
Chris Dutrow

"Position: relative" bulunan bir kutu, ilgili üst kutunun içerik dikdörtgenine göre alt kutular için "üst" ve "sol" (vb.) Ayarını yapar.
Sivri

Yanlış bir şey yapıyor olabilirim, ancak bu firefox'ta çalışmıyor gibi görünüyor. Benim "konum: göreceli;" üst öğeye ayarlandığında, firefox event.pageX ve event.clientX öğelerini aynı şekilde (sayfanın üst kısmına, soluna göre) bildirir ve event.offsetX öğesini tanımsız olarak bildirir
Chris Dutrow

2

İşte size ihtiyacınız olduğunda noktanın yüzde konumunu veren bir tane. https://jsfiddle.net/Themezly/2etbhw01/

function ThzhotspotPosition(evt, el, hotspotsize, percent) {
  var left = el.offset().left;
  var top = el.offset().top;
  var hotspot = hotspotsize ? hotspotsize : 0;
  if (percent) {
    x = (evt.pageX - left - (hotspot / 2)) / el.outerWidth() * 100 + '%';
    y = (evt.pageY - top - (hotspot / 2)) / el.outerHeight() * 100 + '%';
  } else {
    x = (evt.pageX - left - (hotspot / 2));
    y = (evt.pageY - top - (hotspot / 2));
  }

  return {
    x: x,
    y: y
  };
}



$(function() {

  $('.box').click(function(e) {

    var hp = ThzhotspotPosition(e, $(this), 20, true); // true = percent | false or no attr = px

    var hotspot = $('<div class="hotspot">').css({
      left: hp.x,
      top: hp.y,
    });
    $(this).append(hotspot);
    $("span").text("X: " + hp.x + ", Y: " + hp.y);
  });


});
.box {
  width: 400px;
  height: 400px;
  background: #efefef;
  margin: 20px;
  padding: 20px;
  position: relative;
  top: 20px;
  left: 20px;
}

.hotspot {
  position: absolute;
  left: 0;
  top: 0;
  height: 20px;
  width: 20px;
  background: green;
  border-radius: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
  <p>Hotspot position is at: <span></span></p>
</div>


-1

Bunu öneririm:

e.pageX - this.getBoundingClientRect().left
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.