Hujjat (DOM)

Oyna o'lchamlari va skroll

Elementlarnigina emas, butun sahifa (oyna) o'lchamlari va uning skroll holatini ham bilishimiz kerak โ€” masalan, sahifani ma'lum joyga skroll qilish yoki qanchalik skroll qilinganini aniqlash uchun. Ushbu darsda oyna geometriyasini chuqur ko'rib chiqamiz.

Bu yerda muhim nozik nuqta bor: brauzer oynasi o'lchamlarini olish uchun document.documentElement (ya'ni <html>) ishlatiladi, document.body emas. Sabab โ€” body hujjatning to'liq balandligini emas, faqat content'ini o'lchashi mumkin. Quyidagi kodlar faqat brauzerda ishlaydi (statik misollar).

Oyna kengligi/balandligi: clientWidth/clientHeight

Oynaning (viewport โ€” content ko'rinadigan maydon) kengligi va balandligini olish uchun document.documentElementning clientWidth va clientHeight xossalari ishlatiladi:

// oynaning kengligi va balandligi (skrollbardan tashqari)
alert(document.documentElement.clientWidth);  // masalan, 1024
alert(document.documentElement.clientHeight); // masalan, 768
Diqqat! window.innerWidth/innerHeight ham bor, lekin ular skroll panelini ham hisobga oladi. Agar sahifada skrollbar bo'lsa, innerWidth content maydonidan kengroq bo'ladi. Content sig'adigan haqiqiy joyni bilish uchun documentElement.clientWidth aniqroq.
Muhim: <!DOCTYPE HTML> HTML boshida bo'lishi shart. Aks holda geometrik xossalar (masalan, documentElement.clientHeight) noto'g'ri ishlashi mumkin, chunki brauzer eski (quirks) rejimga o'tadi.

Hujjatning to'liq o'lchami: scrollHeight/scrollWidth

Nazariy jihatdan hujjatning to'liq balandligini (skroll qilinadigan joy bilan birga) documentElement.scrollHeightdan olsak bo'ladi. Ammo brauzerlar o'rtasidagi nomuvofiqliklar tufayli ishonchli natija olish uchun bir nechta xossaning maksimumini olish kerak:

let scrollHeight = Math.max(
  document.body.scrollHeight, document.documentElement.scrollHeight,
  document.body.offsetHeight, document.documentElement.offsetHeight,
  document.body.clientHeight, document.documentElement.clientHeight
);

alert('Hujjatning to'liq balandligi: ' + scrollHeight + 'px');
Nega bu murakkab? Chunki turli brauzerlar hujjat balandligini turlicha hisoblaydi. Barcha ehtimoliy qiymatlarning maksimumini olish โ€” barcha brauzerlarda ishonchli ishlaydigan universal usul.

Joriy skroll: pageXOffset / pageYOffset

Oddiy DOM elementlarining joriy skroll holati elem.scrollTop/scrollLeftda bo'ladi. Butun sahifaning joriy skrolli esa window obyektining maxsus xossalarida turadi:

alert('Joriy vertikal skroll: ' + window.pageYOffset);
alert('Joriy gorizontal skroll: ' + window.pageXOffset);

Bularning zamonaviy taxalluslari (alias) ham bor โ€” window.scrollY (= pageYOffset) va window.scrollX (= pageXOffset). Ular bir xil qiymatni beradi:

alert(window.scrollY); // pageYOffset bilan bir xil
alert(window.scrollX); // pageXOffset bilan bir xil
window โ€” global obyekt bo'lgani uchun uni tushirib qoldirib, shunchaki pageYOffset, scrollY deb yozish ham mumkin. Bu xossalar faqat o'qish uchun.

Skrollni boshqarish: scrollTo va scrollBy

Sahifani DOM tuzilmasi to'liq yaratilgandan keyin JavaScript orqali skroll qilish mumkin. Ikki asosiy metod bor:

window.scrollBy(x, y)

Sahifani joriy holatiga nisbatan (x, y) piksel skroll qiladi โ€” ya'ni surib qo'yadi:

window.scrollBy(0, 10); // sahifani 10px pastga suradi (joriy holatdan)
window.scrollBy(0, -10); // 10px yuqoriga suradi

window.scrollTo(pageX, pageY)

Sahifani mutlaq (absolute) koordinataga skroll qiladi โ€” hujjat boshiga nisbatan aniq joyga o'tadi:

window.scrollTo(0, 0);     // sahifani eng yuqoriga qaytaradi
window.scrollTo(0, 500);   // hujjat boshidan 500px pastga o'tadi

Yaqqol taqqoslash: scrollBy โ€” "joriy o'rindan qancha suramiz", scrollTo โ€” "qaysi aniq koordinataga boramiz".

Ikkala metod ham silliq (smooth) skroll uchun obyekt shaklidagi argument qabul qiladi: window.scrollTo({ top: 500, behavior: 'smooth' }). Bu foydalanuvchiga yoqimliroq, animatsiyali skroll beradi.

scrollIntoView bilan elementga skroll qilish

elem.scrollIntoView(top) metodi sahifani elem ko'rinadigan bo'ladigan darajada skroll qiladi. Bitta mantiqiy argument oladi:

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

elem.scrollIntoView();       // elementni oyna tepasiga keltiradi
elem.scrollIntoView(false);  // elementni oyna pastiga keltiradi

Bu metod ham silliq skroll va aniq tekislash uchun obyekt qabul qiladi:

elem.scrollIntoView({
  behavior: 'smooth', // silliq animatsiyali skroll
  block: 'center'     // element vertikal markazga keladi
});
scrollIntoView โ€” sahifadagi ma'lum elementga (masalan, izoh yoki bo'limga) foydalanuvchi diqqatini qaratish uchun juda qulay. Aniq koordinatalarni hisoblash shart emas โ€” brauzer o'zi kerakli joyga suradi.

Skrollni butunlay to'xtatish

Ba'zan sahifani "muzlatib" qo'yish kerak bo'ladi โ€” masalan, ustidan modal oyna (dialog) chiqqanda, orqa fon skroll qilinmasligi uchun. Buning uchun document.body.style.overflow = 'hidden' beriladi:

// sahifa skrollini to'xtatish:
document.body.style.overflow = 'hidden';

// skrollni qaytarish:
document.body.style.overflow = '';
Bu usulning kamchiligi โ€” skrollbar yo'qolganda content biroz "sakrab" ketishi mumkin (skrollbar egallagan joy bo'shab qoladi). Buni kompensatsiya qilish uchun body'ga skrollbar kengligiga teng padding qo'shish mumkin, shunda content joyida qoladi.

Xulosa

Oyna o'lchamlari:

Joriy skroll: window.pageYOffset/pageXOffset (yoki scrollY/scrollX) โ€” faqat o'qish uchun.

Skrollni boshqarish: