Javascript : Koordinat Sistemi

Tarayıcıda iki tür koordinat sistemi vardır.

  1. document ile ilişkili – sıfır noktası sayfanın sol üst köşesinden başlar
  2. window ile ilişkili – sıfır noktası görüntülenen alanın sol üst köşesinden başlar

Koordinat sistemleri

Sayfa scroll yapılmadığı zaman, window ve document koordinatları aynı sıfır noktasından başlar :

coords

Sayfa scroll yapıldıktan sonra sıfır noktası görünen alanın sol üst köşesinden başlar.

coords2

Aslında bu koordinat sistemleri arasında değişim veya çevirme işlemi yapmak basittir. Şöyle ki  : Document koordinatları window koordinatları artı scroll’dur.

Genellikle document koordinatları kullanılırlar çünkü scroll yaptıktan sonrada aynı kalırlar.

offsetParent ile element koordinatları

Element koordinatları sol üst köşeye ait koordinatlardır. Ne yazıkki verdiği koordinat özelliği tek değildir ama offsetParent ve offsetTop/offsetLeft kullanılarak hesaplanabilirler.

offsetSum

Koordinatları hesaplamanın en güzel yolu offsetParent zincirini yukarı hareket ettirmek ve offsetLeft/offsetTop toplamını almaktır. Örnekte olduğu gibi :


function getOffsetSum(elem) {
  var top=0, left=0

  while(elem) {
    top = top + parseInt(elem.offsetTop)
    left = left + parseInt(elem.offsetLeft)
    elem = elem.offsetParent        
  }
   
  return {top: top, left: left}
}

Bu kullanımın iki temek sorunu var.

  1. Farklı browserlarda farklı sonuçlar döndürür. Scroll ve borderlar alınıp hesaplanırken hatalar meydana gelecektir.
  2. Yavaştır. Her zaman offsetParents zinciri üzerinden hareket etmemiz zorunludur.

Aslında tüm bu sorunları çapraz tarayıcı kodlar yazarak gidermek mümkündür ancak biz Internet Explorer 6+, Firefox 3+ и Opera 9.62+, ve modern Safari/Chrome da dahil tüm tarayıcıların desteklediği alternatif çözüm yolunu inceleyelim.

Doğru tercih : elem.getBoundingClientRect

Bu yöntem modern tarayıcıların uyguladığı (IE dahil) ve W3C standatlarında tanımlanmış bir metoddur. Bu metod elemanı çevreleyen bir dikdörtgen döndürür. Dikdörtgen top,left,right,bottom özellikleriye bir nesne olarak verilir.

Sağ alt ve sol üst köşeyi dört sayı temsil eder. Aşağıdaki kodlardan dikdörtgen metodunu inceleyebilirsiniz.


<script type="text/javascript">
function showRect(elem) {
   var r = elem.getBoundingClientRect()
    alert("Top/Left: " + r.top + " / " + r.left);
   alert("Right/Bottom: " + r.right + " / " + r.bottom)
 }
</script>
 <input id="brTest" type="button" value="Goster button.getBoundingClientRect()" onclick='showRect(this)' />

Verilen koordinatlar window ile ilişkilidir document ile değil. Örneğin bu sayfada scroll yaptığınızda buton window top’a gider. Daha sonra “top” koordinatı sıfıra doğru yaklaşır çünkü window ile ilişkilidir. Document ilişkili koordinatları hesaplamak için sayfa scroll hesabını yapmamız gerekiyor.

‘getBoundingClientRect’ metodunu kullanarak yeni versiyon bir koordinat hesaplayıcı üretelim :


function getOffsetRect(elem) {
    // (1)
    var box = elem.getBoundingClientRect()
    
    var body = document.body
    var docElem = document.documentElement
    
    // (2)
    var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop
    var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft
    
    // (3)
    var clientTop = docElem.clientTop || body.clientTop || 0
    var clientLeft = docElem.clientLeft || body.clientLeft || 0
    
    // (4)
    var top  = box.top +  scrollTop - clientTop
    var left = box.left + scrollLeft - clientLeft
    
    return { top: Math.round(top), left: Math.round(left) }
}

Basamaklar  :

  1. Çevrelenen dikdörtgeni alıyoruz.
  2. Sayfa scroll hesaplanıyor. IE <9 dışından tüm tarayıcılar tarafından desteklenir.
  3. Document (“html” yada “body”) IE ‘de sol-üst köşeden kaydırılabilir. Kayma oranı alınıyor.
  4. Tüm döküman koordinatları alınarak “html/body” kayması çıkartlıyor ve window-ilişkili koordinatlara scroll ekleniyor.

Kolay gelsin. 

Muavenet

Web teknolojilerine merak salmış bir bilgisayar mühendisinin yazıları

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir