Elementlarni harakatlantirish uchun koordinatalar bilan tanish boâlishimiz kerak.
JavaScript usullarining koâpchiligi ikkita koordinata tizimidan biri bilan ishlaydi:
- Oynaga nisbatan â
position:fixedga oâxshash, oynaning yuqori/chap chetidan hisoblanadi.- bu koordinatalarni
clientX/clientYdeb belgilaymiz, bunday nomlanishning sababi keyinroq event xususiyatlarini oârganganimizda aniq boâladi.
- bu koordinatalarni
- Hujjatga nisbatan â hujjat ildizidagi
position:absolutega oâxshash, hujjatning yuqori/chap chetidan hisoblanadi.- ularni
pageX/pageYdeb belgilaymiz.
- ularni
Sahifa eng boshigacha skroll qilinganda, yaâni oynaning yuqori/chap burchagi aynan hujjatning yuqori/chap burchagi boâlganda, bu koordinatalar bir-biriga teng boâladi. Ammo hujjat siljigandan keyin, elementlarning oynaga nisbatan koordinatalari oâzgaradi, chunki elementlar oyna boâylab harakatlanadilar, hujjatga nisbatan koordinatalar esa bir xil qoladi.
Ushbu rasmda biz hujjatdagi nuqtani olamiz va skrolldan oldingi (chap) va keyingi (oâng) koordinatalarini koârsatamiz:
Hujjat skroll qilinganda:
pageYâ hujjatga nisbatan koordinata bir xil qoldi, u hujjat yuqorisidan hisoblanadi (hozir skroll qilingan).clientYâ oynaga nisbatan koordinata oâzgaradi (oâq qisqaroq boâldi), chunki xuddi shu nuqta oyna yuqorisiga yaqinroq boâldi.
Element koordinatalari: getBoundingClientRect
elem.getBoundingClientRect() usuli elem ni oârab turgan minimal toârtburchak uchun oyna koordinatalarini oârnatilgan DOMRect sinfi obyekti sifatida qaytaradi.
Asosiy DOMRect xususiyatlari:
x/yâ toârtburchak boshlanishining oynaga nisbatan X/Y koordinatalari,width/heightâ toârtburchakning kengligi/balandligi (manfiy boâlishi mumkin).
Qoâshimcha ravishda, hosila xususiyatlar mavjud:
top/bottomâ yuqori/pastki toârtburchak cheti uchun Y-koordinata,left/rightâ chap/oâng toârtburchak cheti uchun X-koordinata.
Misol uchun, ushbu tugmani bosing va uning oyna koordinatalarini koâring:
Agar sahifani skroll qilsangiz va takrorlasangiz, oynaga nisbatan tugma holati oâzgarganligi sababli, uning oyna koordinatalari (vertikal skroll qilsangiz y/top/bottom) ham oâzgarishini sezasiz.
Mana elem.getBoundingClientRect() natijasining tasviri:
Koârib turganingizdek, x/y va width/height toârtburchakni toâliq tasvirlaydi. Hosila xususiyatlar ulardan osongina hisoblanishi mumkin:
left = xtop = yright = x + widthbottom = y + height
Eâtibor bering:
- Koordinatalar
10.5kabi oânli kasrlar boâlishi mumkin. Bu normal, brauzer ichida hisob-kitoblarda kasrlardan foydalanadi. Bizstyle.left/topga oârnatganda ularni yumaloqlashimiz shart emas. - Koordinatalar manfiy boâlishi mumkin. Masalan, agar sahifa shunday skroll qilinganki,
elemendi oynadan yuqorida boâlsa, u holdaelem.getBoundingClientRect().topmanfiy boâladi.
x/y mavjud boâlsa, nima uchun top/left mavjud?Matematik jihatdan toârtburchak oâzining boshlangâich nuqtasi (x,y) va yoânalish vektori (width,height) bilan noyob tarzda aniqlanadi. Shunday qilib, qoâshimcha hosila xususiyatlar qulaylik uchun.
Texnik jihatdan width/height ning manfiy boâlishi mumkin, bu âyoânaltirilganâ toârtburchak uchun imkon beradi, masalan sichqon tanlovini toâgâri belgilangan boshlanish va oxiri bilan ifodalash uchun.
Mana manfiy width va height boâlgan toârtburchak (masalan width=-200, height=-100):
Koârib turganingizdek, bunday holatda left/top x/y ga teng emas.
Amalda esa elem.getBoundingClientRect() har doim musbat kenglik/balandlik qaytaradi, bu yerda manfiy width/height ni faqat bu bir xil koârinadigan xususiyatlar aslida takrorlanmasligi sababini tushunishingiz uchun eslatamiz.
x/y qoâllab-quvvatlamaydiInternet Explorer tarixiy sabablarga koâra x/y xususiyatlarini qoâllab-quvvatlamaydi.
Shunday qilib, biz yoki polyfill yasashimiz mumkin (DomRect.prototype da getterlar qoâshish) yoki shunchaki top/left dan foydalanishimiz mumkin, chunki ular musbat width/height uchun, xususan elem.getBoundingClientRect() natijasida har doim x/y bilan bir xil.
Oynaga nisbatan koordinatalar va CSS position:fixed oârtasida aniq oâxshashliklar bor.
Ammo CSS joylashtirishda right xususiyati oâng chetdan masofani, bottom xususiyati esa pastki chetdan masofani anglatadi.
Yuqoridagi rasmga nazar tashlaydigan boâlsak, JavaScript da bunday emasligini koâramiz. Barcha oyna koordinatalari chap-yuqori burchakdan hisoblanadi, ularni ham oâz ichiga olgan holda.
elementFromPoint(x, y)
document.elementFromPoint(x, y) ga chaqiruv oyna koordinatalari (x, y) dagi eng ichki joylashgan elementni qaytaradi.
Sintaksis:
let elem = document.elementFromPoint(x, y);
Masalan, quyidagi kod oynaning oârtasida hozir turgan elementni ajratib koârsatadi va uning tegini chiqaradi:
let centerX = document.documentElement.clientWidth / 2;
let centerY = document.documentElement.clientHeight / 2;
let elem = document.elementFromPoint(centerX, centerY);
elem.style.background = "red";
alert(elem.tagName);
Oyna koordinatalaridan foydalanganligi sababli, element joriy skroll holatiga qarab farq qilishi mumkin.
elementFromPoint null qaytaradidocument.elementFromPoint(x,y) usuli faqat (x,y) koârinadigan maydon ichida boâlsa ishlaydi.
Agar koordinatalardan birortasi manfiy boâlsa yoki oyna kengligi/balandligidan oshsa, u null qaytaradi.
Mana uni tekshirmasak yuz berishi mumkin boâlgan tipik xato:
let elem = document.elementFromPoint(x, y);
// agar koordinatalar oynadan tashqarida bo'lsa, elem = null
elem.style.background = ''; // Xato!
âFixedâ joylashtirishda foydalanish
Koâpincha bizga biror narsani joylashtirishda koordinatalar kerak boâladi.
Element yonida biror narsani koârsatish uchun biz uning koordinatalarini olish uchun getBoundingClientRect dan foydalanishimiz va keyin CSS position ni left/top (yoki right/bottom) bilan birga ishlatishimiz mumkin.
Masalan, quyidagi createMessageUnder(elem, html) funksiyasi elem ostida xabar koârsatadi:
let elem = document.getElementById("coords-show-mark");
function createMessageUnder(elem, html) {
// xabar elementi yaratish
let message = document.createElement('div');
// bu yerda uslub uchun css sinfidan foydalanish yaxshiroq
message.style.cssText = "position:fixed; color: red";
// koordinatalar belgilash, "px" ni unutmang!
let coords = elem.getBoundingClientRect();
message.style.left = coords.left + "px";
message.style.top = coords.bottom + "px";
message.innerHTML = html;
return message;
}
// Foydalanish:
// hujjatga 5 soniyaga qo'shish
let message = createMessageUnder(elem, 'Salom, dunyo!');
document.body.append(message);
setTimeout(() => message.remove(), 5000);
Ishga tushirish uchun tugmani bosing:
Kodni chapga, oângga, pastga koârsatish, CSS animatsiyalarini qoâllash va boshqalar uchun oâzgartirish mumkin. Bu oson, chunki bizda elementning barcha koordinatalari va oâlchamlari bor.
Ammo muhim detailga eâtibor bering: sahifa skroll qilinganda xabar tugmadan uzoqlashadi.
Sababi aniq: xabar elementi position:fixed ga tayanadi, shuning uchun sahifa skroll qilinganda oynaning bir xil joyida qoladi.
Buni oâzgartirish uchun bizga hujjat asosidagi koordinatalar va position:absolute dan foydalanish kerak.
Hujjat koordinatalari
Hujjatga nisbatan koordinatalar oyna emas, balki hujjatning chap-yuqori burchagidan boshlanadi.
CSS da oyna koordinatalari position:fixed ga mos keladi, hujjat koordinatalari esa yuqorida joylashgan position:absolute ga oâxshaydi.
Biz biror narsani hujjatning maâlum joyiga qoâyish uchun position:absolute va top/left dan foydalanishimiz mumkin, shunda sahifa skroll qilinayotganda ham u oâsha yerda qoladi. Ammo avval toâgâri koordinatalar kerak.
Elementning hujjat koordinatalarini olish uchun standart usul yoâq. Ammo uni yozish oson.
Ikki koordinata tizimi quyidagi formula bilan bogâlangan:
pageY=clientY+ hujjatning skroll qilingan vertikal qismining balandligi.pageX=clientX+ hujjatning skroll qilingan gorizontal qismining kengligi.
getCoords(elem) funksiyasi elem.getBoundingClientRect() dan oyna koordinatalarini olib, ularga joriy skrollni qoâshadi:
// elementning hujjat koordinatalarini olish
function getCoords(elem) {
let box = elem.getBoundingClientRect();
return {
top: box.top + window.pageYOffset,
right: box.right + window.pageXOffset,
bottom: box.bottom + window.pageYOffset,
left: box.left + window.pageXOffset
};
}
Agar yuqoridagi misolda biz uni position:absolute bilan ishlatsak, xabar skroll qilinganda element yonida qoladi.
Oâzgartirilgan createMessageUnder funksiyasi:
function createMessageUnder(elem, html) {
let message = document.createElement('div');
message.style.cssText = "position:absolute; color: red";
let coords = getCoords(elem);
message.style.left = coords.left + "px";
message.style.top = coords.bottom + "px";
message.innerHTML = html;
return message;
}
Xulosa
Sahifadagi har qanday nuqta koordinatalarga ega:
- Oynaga nisbatan â
elem.getBoundingClientRect(). - Hujjatga nisbatan â
elem.getBoundingClientRect()plus joriy sahifa skrolli.
Oyna koordinatalari position:fixed bilan ishlatish uchun ajoyib, hujjat koordinatalari esa position:absolute bilan yaxshi ishlaydi.
Ikki koordinata tizimi ham oâz afzalliklari va kamchiliklariga ega; bizga baâzida biri yoki boshqasi kerak boâladi, xuddi CSS position absolute va fixed kabi.
Izohlar
<code>yorlig'ini ishlating, bir nechta satrlar uchun - ularni<pre>yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepenâ¦)