Hujjat (DOM)

Element o'lchami va skroll

JavaScript bizga elementlarning kengligi, balandligi va boshqa geometrik xossalari haqida ma'lumot beruvchi ko'plab xususiyatlarni taqdim etadi. Ular elementlarni ko'chirish, joylashtirish yoki skroll holatini aniqlashda zarur. Ushbu darsda asosiy geometrik xossalarni chuqur o'rganamiz.

Barcha o'lcham xossalari sonlar (piksellarda, birliksiz) qaytaradi. Bu ulardan matematik amallarda foydalanishni osonlashtiradi. Bu geometrik kod faqat brauzerda ishlaydi, shuning uchun quyidagi misollar statik.

Namuna element

Xossalarni tushuntirish uchun quyidagi namuna elementdan foydalanamiz. Uning ramkasi (border), otstupi (padding) va skrolli bor:

<div id="example">
  ...Matn...
</div>

<style>
  #example {
    width: 300px;
    height: 200px;
    border: 25px solid #E8C48F; /* ramka */
    padding: 20px;              /* ichki otstup */
    overflow: auto;             /* skroll paydo bo'ladi */
  }
</style>

Bu element ichida skroll paydo bo'lguncha matn bor. Ushbu "quti modeli" (box model) asosida geometrik xossalarni ko'rib chiqamiz: ramka, padding va skroll paneli (scrollbar).

offsetParent, offsetLeft, offsetTop

offsetParent โ€” elementning eng yaqin CSS-joylashtirilgan (positioned) ajdodini qaytaradi. Bu quyidagilardan biri bo'lishi mumkin: eng yaqin position (absolute, relative, fixed, sticky) berilgan ajdod, yoki <td>, <th>, <table>, yoki <body>.

offsetLeft va offsetTop esa elementning offsetParentga nisbatan gorizontal va vertikal x/y koordinatalarini beradi:

<main style="position: relative" id="main">
  <article>
    <div id="example" style="position: absolute; left: 180px; top: 180px">...</div>
  </article>
</main>

<script>
  let example = document.getElementById('example');

  alert(example.offsetParent.id); // main
  alert(example.offsetLeft); // 180 (son, 'px' emas)
  alert(example.offsetTop);  // 180
</script>
offsetParent bir necha holatda null bo'ladi: element ko'rsatilmayotgan bo'lsa (display: none yoki hujjatda emas), yoki <body> va <html> uchun, yoki elementda position: fixed bo'lsa.

offsetWidth va offsetHeight

Bu ikki xossa elementning to'liq tashqi o'lchamini beradi: kenglik va balandlik, ramka (border) bilan birga.

let example = document.getElementById('example');

// width:300 + padding:20*2 + border:25*2 = 390
alert(example.offsetWidth);  // 390

// height:200 + padding:20*2 + border:25*2 = 290
alert(example.offsetHeight); // 290
Yashirilgan elementlar (display: none yoki hujjatda bo'lmagan) uchun barcha geometrik xossalar nol (yoki null โ€” offsetParent uchun) bo'ladi. Buni elementning ko'rinadigan-ko'rinmasligini tekshirish uchun ishlatish mumkin: agar offsetWidth va offsetHeight nol bo'lsa, element yashirin.

clientTop, clientLeft

Bu xossalar elementning ramka (border) qalinliklarini beradi โ€” aniqrog'i, ichki tomondan ramka chegarasigacha bo'lgan masofa. Odatda ular yuqori va chap ramka kengligiga teng:

// yuqorida border: 25px berilgan edi
alert(example.clientTop);  // 25
alert(example.clientLeft); // 25
Aniqrog'i, bular ramka o'lchami emas, balki ichki (content + padding) qismning tashqi qirrasidan elementning tashqi qirrasigacha bo'lgan masofa. Chapdan o'ngga yoziladigan tillar uchun ular chap/yuqori ramka kengligiga teng.

clientWidth va clientHeight

Bu xossalar ramka ichidagi maydon o'lchamini beradi โ€” ya'ni content + padding, lekin skroll paneli (scrollbar) hisobga olinmaydi:

let example = document.getElementById('example');

// width:300 + padding:20*2 = 340
// (border qo'shilmaydi, skrollbar chiqmasa)
alert(example.clientWidth);  // 340

// height:200 + padding:20*2 = 240
alert(example.clientHeight); // 240
Agar elementda vertikal skroll paneli mavjud bo'lsa, u clientWidthdan o'zining kengligini (odatda ~16px) "o'g'irlaydi", chunki skrollbar content uchun mavjud joyni egallaydi. Shuning uchun skrollbar chiqqanda clientWidth kutilganidan kichikroq bo'lishi mumkin.
Ba'zan clientWidth/Height bo'sh maydonni o'lchash uchun ishlatiladi. offsetWidthdan farqi โ€” u ramkani hisobga olmaydi va skrollbardan tashqari content'ga tegishli maydonni beradi.

scrollWidth va scrollHeight

Bu xossalar clientWidth/clientHeight kabidir, ammo skroll tufayli yashiringan (ko'rinmaydigan) qismni ham hisobga oladi:

let example = document.getElementById('example');

// element ichidagi to'liq content balandligi
alert(example.scrollHeight); // masalan, 723 (barcha matn)
alert(example.clientHeight); // 240 (faqat ko'rinadigan qism)

Bu xossalar yordamida elementni to'liq balandligacha "kengaytirish" mumkin โ€” masalan, matn maydonini (textarea) content sig'adigan qilib kattalashtirish:

let element = document.getElementById('element');

// element balandligini to'liq content sig'adigan qilib kengaytiramiz
element.style.height = element.scrollHeight + 'px';
Agar scrollHeight clientHeightdan katta bo'lsa, demak elementda vertikal skroll bor โ€” content ko'rinadigan maydondan uzun.

scrollTop va scrollLeft

scrollLeft va scrollTop โ€” elementning yashiringan, skroll qilib o'tkazilgan qismining kengligi/balandligini beradi. Boshqacha aytganda, scrollTop โ€” bu "yuqoriga qancha skroll qilinganini" bildiradi.

let element = document.getElementById('element');

alert(element.scrollTop); // masalan, 150 (150px yuqoriga skroll qilingan)

Ko'pgina geometrik xossalar faqat o'qish uchun bo'lsa-da, scrollTop va scrollLeftni o'zgartirish mumkin โ€” brauzer elementni shu holatga skroll qiladi:

let element = document.getElementById('element');

element.scrollTop = 0;   // elementni eng yuqoriga skroll qiladi
element.scrollTop = 1e9; // katta son bersak โ€” eng pastga skroll qiladi
// (brauzer maksimal mumkin bo'lgan qiymatni oladi)
scrollTopga juda katta son (masalan, 1e9 = milliard) berish โ€” elementni eng pastgacha skroll qilishning ishonchli usuli. Brauzer bu qiymatni maksimal ruxsat etilgan darajaga qisqartiradi.

getBoundingClientRect โ€” qisqacha

Yuqoridagi offset*/client*/scroll* xossalari elementning o'z ichki geometriyasi bilan ishlaydi. Elementning ekrandagi (oyna) joylashuvini aniq bilish uchun esa getBoundingClientRect() ishlatiladi:

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

alert(rect.top);    // elementning yuqori qirrasi (oyna tepasidan)
alert(rect.left);   // elementning chap qirrasi (oyna chapidan)
alert(rect.width);  // elementning kengligi
alert(rect.height); // elementning balandligi
alert(rect.right);  // o'ng qirra (oyna chapidan)
alert(rect.bottom); // pastki qirra (oyna tepasidan)

U DOMRect obyektini qaytaradi โ€” bu obyekt elementni o'rab turgan minimal to'rtburchakning oynaga (viewport) nisbatan koordinatalarini o'z ichiga oladi. Bu haqda batafsil "Koordinatalar" darsida gaplashamiz.

Muhim farq: offsetTop/Left โ€” offsetParentga nisbatan, o'zgarmas (skrolldan mustaqil). getBoundingClientRect esa โ€” oynaga (viewport) nisbatan, shuning uchun sahifani skroll qilsangiz, uning qiymatlari o'zgaradi.

Xulosa

Elementning asosiy geometrik xossalari:

Barcha xossalar sonlarda (piksel) qaytadi. Ekrandagi joylashuvni aniqlash uchun esa getBoundingClientRect().