Hujjat (DOM)

Koordinatalar

Elementlarni ekranda aniq joyga qo'yish uchun (masalan, tooltip yoki kontekst menyu) ularning koordinatalarini bilishimiz kerak. JavaScript'da ikkita asosiy koordinata tizimi bor va ularni chalkashtirmaslik juda muhim. Ushbu darsda ikkalasini ham chuqur o'rganamiz.

Ikki koordinata tizimi

Har bir nuqtani (masalan, elementning qirrasini) ikki xil boshlanish nuqtasidan (koordinata boshi) o'lchash mumkin:

Sahifa yuqoriga skroll qilinmagan (eng boshida) bo'lsa, oyna va hujjat koordinatalari bir xil bo'ladi. Ammo skroll qilingandan keyin ular farqlanadi: pageY = clientY + skroll_balandligi.

Ular o'rtasidagi bog'liqlik:

// aniq formula (vertikal uchun):
pageY = clientY + window.pageYOffset;

// gorizontal uchun:
pageX = clientX + window.pageXOffset;

Element koordinatalari: getBoundingClientRect

elem.getBoundingClientRect() metodi elementni o'rab turgan minimal to'rtburchakning oynaga nisbatan (window) koordinatalarini DOMRect obyekti sifatida qaytaradi. Uning asosiy xossalari:

let elem = document.getElementById('elem');
let rect = elem.getBoundingClientRect();

alert('Yuqori (top): ' + rect.top);
alert('Chap (left): ' + rect.left);
alert('Kenglik: ' + rect.width);
alert('Balandlik: ' + rect.height);

Muhim munosabatlar (odatda):

Nega alohida x/y va left/top, ular bir xilku? Chunki width/height manfiy bo'lishi mumkin (masalan, o'ngdan chapga yozuvda). U holda x/y โ€” to'rtburchak boshi, ammo left undan kichikroq bo'lishi mumkin. Amalda esa ko'p hollarda ular bir xil.
getBoundingClientRect koordinatalari oynaga nisbatan, hujjatga emas. Shuning uchun sahifani skroll qilsangiz, element joyida tursa ham, top/left o'zgaradi. Bu, masalan, position: fixed element qo'yish uchun aynan qulay.
IE va Edge'ning eski versiyalarida getBoundingClientRect natijasida x/y xossalari bo'lmasligi mumkin edi. Agar shunday holatga duch kelsangiz, left/topdan foydalaning โ€” ular hamma joyda mavjud.

elementFromPoint(x, y)

document.elementFromPoint(x, y) metodi berilgan oyna koordinatalaridagi (clientX, clientY) eng ichkarida, ustki qatlamda joylashgan elementni qaytaradi:

// oyna markazidagi elementni topamiz:
let centerX = document.documentElement.clientWidth / 2;
let centerY = document.documentElement.clientHeight / 2;

let elem = document.elementFromPoint(centerX, centerY);

alert(elem.tagName); // shu nuqtadagi element teg nomi
elem.style.background = 'red'; // uni ajratib ko'rsatamiz
Koordinatalar oynaga nisbatan berilishi kerak (clientX/clientY), hujjatga emas. Bundan tashqari, oyna tashqarisidagi koordinatalar (manfiy yoki oyna o'lchamidan katta) uchun elementFromPoint null qaytaradi โ€” bunday holatlarni tekshirmasangiz, null.style kabi xatolikka duch kelasiz.

Koordinatalar orqali joylashtirish: position fixed

Biror elementni ma'lum bir joyga (masalan, boshqa element yoniga tooltip) qo'yish uchun ko'pincha position: fixed va getBoundingClientRect koordinatalari birga ishlatiladi, chunki fixed ham oynaga nisbatan joylashadi:

function createTipUnder(anchor, html) {
  let tip = document.createElement('div');
  tip.style.cssText = 'position: fixed; padding: 5px; background: yellow;';
  tip.innerHTML = html;

  document.body.append(tip);

  // anchor elementning oynaga nisbatan joyi:
  let coords = anchor.getBoundingClientRect();

  // tooltip'ni anchor ostiga qo'yamiz:
  tip.style.left = coords.left + 'px';
  tip.style.top = coords.bottom + 5 + 'px';
}
position: fixed muammosi โ€” sahifa skroll qilinganda tooltip joyida qotib qoladi (anchor bilan birga ketmaydi), chunki fixed oynaga bog'langan. Agar tooltip anchor bilan birga skroll qilinishini istasangiz, hujjat koordinatalari va position: absolute kerak bo'ladi.

Hujjat koordinatalari: position absolute

Tooltip sahifa bilan birga skroll qilinishi uchun uni hujjat koordinatalari asosida position: absolute bilan joylashtiramiz. Buning uchun oyna koordinatasiga joriy skrollni qo'shamiz:

// element uchun hujjatga nisbatan koordinatalarni hisoblovchi funksiya
function getCoords(elem) {
  let box = elem.getBoundingClientRect();

  return {
    top: box.top + window.pageYOffset,
    left: box.left + window.pageXOffset,
    bottom: box.bottom + window.pageYOffset,
    right: box.right + window.pageXOffset
  };
}

Endi tooltip'ni position: absolute bilan hujjat koordinatalariga qo'ysak, u sahifa bilan birga skroll qilinadi:

function createTipUnder(anchor, html) {
  let tip = document.createElement('div');
  tip.style.cssText = 'position: absolute; padding: 5px; background: yellow;';
  tip.innerHTML = html;

  document.body.append(tip);

  let coords = getCoords(anchor); // hujjat koordinatalari

  tip.style.left = coords.left + 'px';
  tip.style.top = coords.bottom + 5 + 'px';
}
Xulosaviy tanlov: elementni oynaga bog'lash kerak bo'lsa (skrolldan qat'i nazar joyida qolsin) โ€” position: fixed va oyna koordinatalari (getBoundingClientRect). Elementni sahifa content'iga bog'lash kerak bo'lsa (skroll bilan ketsin) โ€” position: absolute va hujjat koordinatalari (skroll qo'shilgan).

Xulosa

Nuqtaning ikkita koordinatasi bor:

Asosiy vositalar:

Ushbu bilimlar bilan siz endi elementlarni ekranda aniq joylashtirishingiz, tooltip va menyular yaratishingiz mumkin. Bu โ€” interaktiv interfeyslar qurishning poydevoridir.