UI hodisalari

Pointer hodisalari

Pointer hodisalari (Pointer Events) โ€” sichqoncha, sensorli ekran va qalam (stylus) kabi turli ko'rsatuvchi qurilmalar bilan ishlashning zamonaviy va yagona usuli. Ular sichqoncha hodisalarining o'rnini bosishga mo'ljallangan va bugungi kunda barcha zamonaviy brauzerlarda qo'llab-quvvatlanadi.

Bu darsdagi kod misollari statik โ€” pointer hodisalari playground'da ishlamaydi. Ularni haqiqiy sahifada sinang.

Qisqacha tarix

Uzoq vaqt faqat sichqoncha hodisalari mavjud edi. Keyin sensorli qurilmalar (telefon, planshet) tarqaldi va ular uchun touchstart, touchmove, touchend kabi Touch Events paydo bo'ldi. Muammo shundaki, dasturchilarga bir vaqtda ikki xil (sichqoncha va sensor) API'ni qo'llab-quvvatlashga to'g'ri kelardi โ€” bu ko'p takroriy kod demakdir.

Buni hal qilish uchun Pointer Events standarti yaratildi. U barcha turdagi ko'rsatuvchi qurilmalarni bitta yagona API ostida birlashtiradi. Bugun eng so'nggi versiya โ€” Pointer Events Level 2 โ€” barcha asosiy brauzerlarda ishlaydi.

Pointer hodisalari turlari

Pointer hodisalarining nomlari sichqoncha hodisalariga o'xshaydi โ€” faqat mouse o'rniga pointer:

Ko'p hollarda mavjud mouse... hodisa nomlarini pointer...ga almashtirishning o'zi kifoya qiladi โ€” kod sichqoncha, sensor va qalamda barobar ishlay boshlaydi. Bu Pointer Events'ning eng katta afzalligi.

pointerType: qurilma turini aniqlash

Pointer hodisalari sichqoncha hodisalarining barcha xossalarini (clientX/Y, target, button va h.k.) meros qilib oladi. Bundan tashqari o'ziga xos yangi xossalar bor. Eng foydalisi โ€” pointerType. U qaysi turdagi qurilma hodisani chaqirganini bildiradi:

elem.onpointerdown = function(event) {
  if (event.pointerType === 'touch') {
    // Barmoq bilan bosildi
  } else if (event.pointerType === 'pen') {
    // Qalam bilan
  } else {
    // Sichqoncha bilan
  }
};

Bu bizga qurilma turiga qarab turlicha xatti-harakat qilish imkonini beradi โ€” bir xil kod ichida, ikkita alohida API'siz.

pointerId: bir nechta barmoqni ajratish

Har bir ko'rsatuvchining o'ziga xos identifikatori bor โ€” pointerId. Sichqoncha bilan ishlaganda bu odatda muhim emas (bitta kursor). Lekin sensorli ekranlarda ko'p barmoqli (multi-touch) harakatlar bo'lishi mumkin โ€” masalan, ikki barmoq bilan kattalashtirish (pinch-zoom).

Har bir barmoqqa alohida pointerId beriladi. Shu tufayli bir vaqtning o'zida bir nechta ko'rsatuvchini alohida-alohida kuzatish mumkin:

elem.onpointerdown = function(event) {
  console.log('Yangi pointer, ID: ' + event.pointerId);
  // Har bir barmoq uchun turli pointerId keladi
};
Ko'p barmoqli interfeyslar (masalan, virtual pianino yoki multi-touch chizma dasturi) yaratishda pointerId markaziy rol o'ynaydi โ€” u har bir barmoqni alohida obyekt sifatida boshqarishga yordam beradi. Bu Touch Events bilan ancha mashaqqatliroq edi.

isPrimary xossasi

Bir nechta ko'rsatuvchi bir vaqtda bo'lsa (masalan, bir nechta barmoq), event.isPrimary xossasi "birlamchi" (asosiy) ko'rsatuvchi uchun true qaytaradi โ€” bu odatda birinchi tegilgan barmoq. Bu bilan asosiy harakatni ikkilamchilaridan ajratish mumkin.

setPointerCapture: pointer'ni ushlab qolish

Pointer Events'ning kuchli imkoniyatlaridan biri โ€” elem.setPointerCapture(pointerId) metodi. U berilgan pointerIdga tegishli barcha kelgusi hodisalarni shu elemga "biriktirib qo'yadi" (bind qiladi).

Ya'ni setPointerCapture chaqirilgandan so'ng, ko'rsatuvchi qayerda bo'lishidan qat'i nazar (hatto element chegarasidan tashqariga chiqsa ham), barcha pointer hodisalari maqsad qilingan elementga yo'naltiriladi โ€” event.target har doim o'sha element bo'ladi.

// Slayder (slider) yasashda foydali:
slider.onpointerdown = function(event) {
  // Endi bu pointer'ning barcha hodisalari slider'ga keladi,
  // kursor slider tashqarisiga chiqib ketsa ham.
  slider.setPointerCapture(event.pointerId);
};

slider.onpointermove = function(event) {
  // Slayder tashqarisida ham ishlaydi!
};
Capture avtomatik ravishda pointerup yoki pointercancel yuzaga kelganda bekor qilinadi. Uni qo'lda bekor qilish uchun elem.releasePointerCapture(pointerId) ishlatiladi.
Oldingi darsdagi Drag'n'Drop yoki slayder misolini eslang: u yerda mousemoveni documentga bog'lashimiz kerak edi, aks holda kursor element tashqarisiga chiqsa hodisa yo'qolardi. setPointerCapture bilan bu muammo o'z-o'zidan hal bo'ladi โ€” ishlov beruvchilarni hujjatga ko'chirish shart emas, kod ancha toza bo'ladi.

gotpointercapture va lostpointercapture

Capture olingan va yo'qolgan paytlarni kuzatish uchun ikki hodisa bor: gotpointercapture (element pointer'ni ushlaganda) va lostpointercapture (ushlash tugaganda). Odatda ular kamdan-kam kerak bo'ladi, lekin murakkab holatlarni to'g'ri boshqarishda yordam beradi.

Xulosa

Zamonaviy loyihalarda interaktivlik uchun Touch Events yoki alohida sichqoncha hodisalari o'rniga Pointer Events'dan foydalanish tavsiya etiladi.