Pointer hodisalari sichqoncha, qalam/stylus, sensorli ekran va boshqalar kabi turli xil koârsatkich qurilmalaridan kirishni boshqarishning zamonaviy usulidir.
Qisqacha tarix
Kichik sharh beramiz, shunda siz umumiy rasmni va Pointer hodisalarning boshqa hodisa turlari orasidagi oârnini tushunasiz.
-
Uzoq vaqt oldin, oâtmishda faqat sichqoncha hodisalari mavjud edi.
Keyin sensorli qurilmalar, xususan telefonlar va planshetlar keng tarqaldi. Mavjud skriptlar ishlashi uchun ular sichqoncha hodisalarini hosil qildi (va hali ham qiladilar). Masalan, sensorli ekranga tegish
mousedownni hosil qiladi. Shuning uchun sensorli qurilmalar veb-sahifalar bilan yaxshi ishladi.Lekin sensorli qurilmalar sichqonchadan koâproq imkoniyatlarga ega. Masalan, bir vaqtda bir nechta nuqtaga tegish mumkin (âmulti-touchâ). Garchi, sichqoncha hodisalarida bunday multi-touchlarni qayta ishlash uchun kerakli xossalar yoâq.
-
Shuning uchun
touchstart,touchend,touchmovekabi touch hodisalari kiritildi, ularda touchga xos xossalar bor (biz ularni batafsil koârib chiqmaymiz, chunki pointer hodisalari yanada yaxshiroq).Shunga qaramay, bu yetarli emas edi, chunki qalam kabi oâziga xos xususiyatlarga ega koâplab boshqa qurilmalar mavjud. Bundan tashqari, ham touch, ham sichqoncha hodisalarini tinglovchi kod yozish mashaqqatli edi.
-
Bu muammolarni hal qilish uchun yangi standart Pointer hodisalari kiritildi. U barcha turdagi koârsatkich qurilmalari uchun yagona hodisalar toâplamini taqdim etadi.
Hozirda Pointer Events Level 2 spetsifikatsiyasi barcha asosiy brauzerlarda qoâllab-quvvatlanadi, yangi Pointer Events Level 3 esa ishlab chiqilmoqda va asosan Pointer Events level 2 bilan mos keladi.
Agar siz Internet Explorer 10 yoki Safari 12 va undan pastroq kabi eski brauzerlar uchun ishlab chiqmasangiz, endi sichqoncha yoki touch hodisalaridan foydalanishning maânosi yoâq â biz pointer hodisalariga oâtishimiz mumkin.
Shunda kodingiz ham touch, ham sichqoncha qurilmalari bilan yaxshi ishlaydi.
Shu bilan birga, Pointer hodisalarini toâgâri ishlatish va kutilmagan holatlardan qochish uchun bilish kerak boâlgan baâzi muhim xususiyatlar mavjud. Biz ularni ushbu maqolada qayd etamiz.
Pointer hodisa turlari
Pointer hodisalari sichqoncha hodisalariga oâxshash nomlanadi:
| Pointer hodisasi | Oâxshash sichqoncha hodisasi |
|---|---|
pointerdown |
mousedown |
pointerup |
mouseup |
pointermove |
mousemove |
pointerover |
mouseover |
pointerout |
mouseout |
pointerenter |
mouseenter |
pointerleave |
mouseleave |
pointercancel |
- |
gotpointercapture |
- |
lostpointercapture |
- |
Koârib turganimizdek, har bir mouse<event> uchun oâxshash rol oâynaydigan pointer<event> mavjud. Bundan tashqari, mos keladigan mouse... qariydoshi boâlmagan 3 ta qoâshimcha pointer hodisasi mavjud, biz ularni tez orada tushuntiramiz.
mouse<event> ni pointer<event> bilan almashtirishBiz kodimizdagi mouse<event> hodisalarini pointer<event> bilan almashtirshimiz va sichqoncha bilan ishlashda davom etishini kutishimiz mumkin.
Sensorli qurilmalar uchun qoâllab-quvvatlash ham âsehrliâ tarzda yaxshilanadi. Garchi, CSS da baâzi joylarda touch-action: none qoâshishimiz kerak boâlishi mumkin. Buni quyida pointercancel haqidagi boâlimda koârib chiqamiz.
Pointer hodisa xossalari
Pointer hodisalari sichqoncha hodisalari bilan bir xil xossalarga ega, masalan clientX/Y, target va h.k., shuningdek baâzi boshqalar:
-
pointerIdâ hodisani keltirib chiqaruvchi pointerning noyob identifikatori.Brauzer tomonidan yaratiladi. Koâp pointerlarni qayta ishlashga imkon beradi, masalan stylusli sensorli ekran va multi-touch (misollar keyinroq keladi).
-
pointerTypeâ koârsatkich qurilmasi turi. Satr boâlishi kerak, quyidagilardan biri: âmouseâ, âpenâ yoki âtouchâ.Biz bu xossani turli pointer turlariga turlicha javob berish uchun ishlatishimiz mumkin.
-
isPrimaryâ asosiy pointer uchuntrue(multi-touchda birinchi barmoq).
Baâzi pointer qurilmalari kontakt maydoni va bosimni oâlchaydi, masalan sensorli ekrandagi barmoq uchun buning uchun qoâshimcha xossalar mavjud:
widthâ pointer (masalan barmoq) qurilmaga teginadigan maydonning kengligi. Qoâllab-quvvatlanmagan joylarda, masalan sichqoncha uchun, u doim1.heightâ pointer qurilmaga teginadigan maydonning balandligi. Qoâllab-quvvatlanmagan joylarda, u doim1.pressureâ pointer uchining bosimi, 0 dan 1 gacha diapazonda. Bosimni qoâllab-quvvatlamaydigan qurilmalar uchun0.5(bosilgan) yoki0boâlishi kerak.tangentialPressureâ normallashtirilgan tangensial bosim.tiltX,tiltY,twistâ qalamga xos xossalar, qalam sirtga nisbatan qanday joylashganini tasvirlaydi.
Bu xossalar koâpchilik qurilmalarda qoâllab-quvvatlanmaydi, shuning uchun kamdan-kam ishlatiladi. Kerak boâlsa, ular haqida batafsil maâlumotni spetsifikatsiyada topishingiz mumkin.
Multi-touch
Sichqoncha hodisalari umuman qoâllab-quvvatlamaydigan narsalardan biri multi-touch: foydalanuvchi telefon yoki planshetida bir vaqtda bir nechta joyga tegishi yoki maxsus imo-ishoralar bajarishi mumkin.
Pointer hodisalari pointerId va isPrimary xossalari yordamida multi-touchni qayta ishlashga imkon beradi.
Foydalanuvchi sensorli ekranning bir joyiga tegganda, keyin boshqa barmoqni boshqa joyga qoâyganda nima sodir boâladi:
- Birinchi barmoq teginishida:
isPrimary=trueva birorpointerIdbilanpointerdown.
- Ikkinchi barmoq va koâproq barmoqlar uchun (birinchisi hali teginayotgan deb faraz qilsak):
- har bir barmoq uchun
isPrimary=falseva boshqapointerIdbilanpointerdown.
- har bir barmoq uchun
Diqqat qiling: pointerId butun qurilmaga emas, balki har bir teginuvchi barmoq uchun tayinlanadi. Agar biz 5 barmoq bilan bir vaqtda ekranga tegadigan boâlsak, bizda 5 ta pointerdown hodisasi boâladi, har biri oâz koordinatalari va boshqa pointerId bilan.
Birinchi barmoq bilan bogâliq hodisalar doim isPrimary=true ga ega.
Biz ularning pointerId yordamida koâplab teginuvchi barmoqlarni kuzatishimiz mumkin. Foydalanuvchi barmoqni harakat qildirganda va keyin olib tashlaganda, biz pointerdown da boâlgani kabi bir xil pointerId bilan pointermove va pointerup hodisalarini olamiz.
Mana pointerdown va pointerup hodisalarini qayd qiluvchi demo:
Diqqat qiling: pointerId/isPrimary dagi farqni haqiqatdan ham koârish uchun telefon yoki planshet kabi sensorli ekran qurilmasidan foydalanish kerak. Sichqoncha kabi bitta teginish qurilmalari uchun barcha pointer hodisalar uchun doim isPrimary=true bilan bir xil pointerId boâladi.
Hodisa: pointercancel
pointercancel hodisasi davom etayotgan pointer oâzaro taâsir boâlganda ishga tushadi va keyin uni bekor qiladigan narsa sodir boâladi, shuning uchun boshqa pointer hodisalar hosil boâlmaydi.
Bunday sabablar:
- Pointer qurilmasi apparati jismonan oâchirilgan.
- Qurilma orientatsiyasi oâzgargan (planshet aylantirilgan).
- Brauzer oâzaro taâsirni oâzi boshqarishga qaror qilgan, uni sichqoncha harakati yoki zoom va pan harakati yoki boshqa narsa deb hisoblagan.
pointercancel ni bizga qanday taâsir qilishini koârish uchun amaliy misolda namoyish etamiz.
Aytaylik, biz Sichqoncha hodisalari bilan Drag'n'Drop maqolasining boshidagi kabi toâp uchun dragânâdrop ni amalga oshirmoqdamiz.
Mana foydalanuvchi harakatlari oqimi va tegishli hodisalar:
- Foydalanuvchi sudrab boshlash uchun rasmga bosadi
pointerdownhodisasi ishga tushadi
- Keyin ular pointerni harakatlantira boshlaydi (shu bilan rasmni sudraydi)
pointermoveishga tushadi, ehtimol bir necha marta
- Va keyin kutilmagan narsa sodir boâladi! Brauzerni rasmlar uchun mahalliy dragânâdrop qoâllab-quvvatlashi kirib, dragânâdrop jarayonini oâz qoâliga olib,
pointercancelhodisasini hosil qiladi.- Brauzer endi rasmni dragânâdrop ini oâzi boshqaradi. Foydalanuvchi hatto toâp rasmini brauzerdan tashqariga, Mail dasturiga yoki Fayl menejeriga sudrab olib ketishi mumkin.
- Biz uchun boshqa
pointermovehodisalari yoâq.
Demak, muammo shundaki, brauzer oâzaro taâsirni âoâgâirlaydiâ: âdrag-and-dropâ jarayonining boshida pointercancel ishga tushadi va boshqa pointermove hodisalari hosil boâlmaydi.
Mana pointer hodisalarini qayd qiluvchi dragânâdrop demosi (textarea da faqat up/down, move va cancel):
Biz dragânâdrop ni oâzimiz amalga oshirmoqchimiz, shuning uchun brauzerni buni oâz qoâliga olmasligini ayting.
pointercancel dan qochish uchun standart brauzer harakatining oldini oling.
Bizga ikki narsa qilish kerak:
- Mahalliy dragânâdrop sodir boâlishining oldini olish:
- Buni Sichqoncha hodisalari bilan Drag'n'Drop maqolasida tasvirlanganidek
ball.ondragstart = () => falseoârnatish orqali qilishimiz mumkin. - Bu sichqoncha hodisalari uchun yaxshi ishlaydi.
- Buni Sichqoncha hodisalari bilan Drag'n'Drop maqolasida tasvirlanganidek
- Sensorli qurilmalar uchun boshqa touch bilan bogâliq brauzer harakatlari (dragânâdrop dan tashqari) mavjud. Ular bilan ham muammolardan qochish uchun:
- CSS da
#ball { touch-action: none }oârnatish orqali ularning oldini oling. - Keyin kodimiz sensorli qurilmalarda ishlay boshlaydi.
- CSS da
Buni qilganimizdan soâng, hodisalar moâljallanganidek ishlaydi, brauzer jarayonni oâgâirlamaydi va pointercancel chiqarmaydi.
Bu demo ushbu qatorlarni qoâshadi:
Koârib turganimizdek, endi pointercancel yoâq.
Endi biz toâpni haqiqatdan ham harakatlantirish uchun kod qoâshishimiz mumkin va bizning dragânâdrop sichqoncha qurilmalari va sensorli qurilmalar uchun ishlaydi.
Pointer capturing
Pointer capturing â pointer hodisalarining maxsus xususiyatidir.
Gâoya juda oddiy, lekin avvaliga juda gâalati tuyulishi mumkin, chunki boshqa hodisa turlari uchun bunday narsa mavjud emas.
Asosiy usul:
elem.setPointerCapture(pointerId)â berilganpointerIdbilan hodisalarnielemga bogâlaydi. Chaqiruvdan keyin bir xilpointerIdga ega barcha pointer hodisalarelemni target sifatida oladilar (xuddielemda sodir boâlgandek), hujjatda qayerda sodir boâlishidan qatâi nazar.
Boshqacha qilib aytganda, elem.setPointerCapture(pointerId) berilgan pointerId bilan barcha keyingi hodisalarni elem ga qayta yoânaltiradi.
Bogâlanish olib tashlanadi:
pointerupyokipointercancelhodisalari sodir boâlganda avtomatik,elemhujjatdan olib tashlanganida avtomatik,elem.releasePointerCapture(pointerId)chaqirilganda.
Pointer capturing dragânâdrop kabi oâzaro taâsirlarni soddalashtirish uchun ishlatilishi mumkin.
Misol sifatida Sichqoncha hodisalari bilan Drag'n'Drop da tasvirlangan maxsus slaydernà qanday amalga oshirishni eslaymiz.
Biz ichida tasmasi va ârunnerâ (thumb) bor slaydeir elementini yaratamiz.
Keyin u shunday ishlaydi:
- Foydalanuvchi slaydeir
thumbni bosadi âpointerdownishga tushadi. - Keyin ular pointerni harakatlantiradi â
pointermoveishga tushadi va bizthumbni harakatlantiramy.- â¦Pointer harakat qilarkan, u slaydeir
thumbdan chiqib ketishi mumkin: ustiga yoki pastiga borishi.thumbqatâiy gorizontal harakat qilishi, pointer bilan hizalanib qolishi kerak.
- â¦Pointer harakat qilarkan, u slaydeir
Shuning uchun barcha pointer harakatlarini kuzatish uchun, shu jumladan thumb ustiga/pastiga boriÅ¡Ãda ham, biz pointermove hodisa iÅlov beruvchisini butun document ga tayinlashimiz kerak edi.
Bu yechim biroz âiflosâ koârinadi. Muammolardan biri shundaki, hujjat atrofidagi pointer harakatlari yon taâsirlarni keltirib chiqarishi, slaydeir bilan umuman bogâliq boâlmagan boshqa hodisa ishlov beruvchilarni ishga tushirishi mumkin.
Pointer capturing pointermove ni thumb ga bogâlash va bunday muammolardan qochish vositasini beradi:
- Biz
pointerdownishlov beruvchidathumb.setPointerCapture(event.pointerId)ni chaqirshimiz mumkin, - Keyin
pointerup/cancelgacha boâlgan kelajak pointer hodisalarthumbga qayta yoânaltiriladi. pointerupsodir boâlganda (sudrab tugatilganda), bogâlanish avtomatik olib tashlanadi, bu haqida gâamxoârlik qilishimiz shart emas.
Shunday qilib, foydalanuvchi pointerni butun hujjat boâylab harakatlantirsa ham, hodisa ishlov beruvchilar thumb da chaqiriladi. Bundan tashqari, hodisa obyektlarining koordinata xossalari, masalan clientX/clientY hali ham toâgâri boâladi â capturing faqat target/currentTarget ga taâsir qiladi.
Mana asosiy kod:
thumb.onpointerdown = function(event) {
// barcha pointer hodisalarni (pointerup gacha) thumb ga qayta yo'naltirish
thumb.setPointerCapture(event.pointerId);
};
thumb.onpointermove = function(event) {
// slayderni harakatlantirish: thumb ni tinglaymiz, chunki barcha pointer hodisalar unga qayta yo'naltiriladi
let newLeft = event.clientX - slider.getBoundingClientRect().left;
thumb.style.left = newLeft + 'px';
};
// diqqat: thumb.releasePointerCapture ni chaqirish shart emas,
// u pointerup da avtomatik sodir bo'ladi
Toâliq demo:
Oxir-oqibat, pointer capturing bizga ikkita foyda beradi:
- Kod tozaroq boâladi, chunki biz endi butun
documentda ishlov beruvchilarni qoâshish/olib tashlashimiz shart emas. Bogâlanish avtomatik ravishda chiqariladi. - Agar hujjatda biror
pointermoveishlov beruvchilar boâlsa, foydalanuvchi slayderni sudrab ketayotganda pointer tomonidan ular tasodifan ishga tushmaydi.
Pointer capturing hodisalari
Ikkita bogâliq pointer hodisasi mavjud:
gotpointercaptureâ element capturing ni yoqish uchunsetPointerCapturedan foydalanganda ishga tushadi.lostpointercaptureâ capturing chiqarilganda ishga tushadi:releasePointerCapturechaqiruvi bilan aniq yokipointerup/pointercancelda avtomatik.
Xulosa
Pointer hodisalari sichqoncha, touch va qalam hodisalarini bir vaqtda, yagona kod qismi bilan qayta ishlash imkonini beradi.
Pointer hodisalari sichqoncha hodisalarini kengaytiradi. Biz hodisa nomlarida mouse ni pointer bilan almashtirishimiz mumkin va kodimiz sichqoncha uchun ishlashda davom etishini, boshqa qurilma turlari uchun yaxshiroq qoâllab-quvvatlash bilan kutishimiz mumkin.
Dragânâdroplar va brauzer oâzi hijack qilish va boshqarishga qaror qilishi mumkin boâlgan murakkab touch oâzaro taâsirlar uchun â hodisalarda standart harakatni bekor qilishni va biz ishtirok etadigan elementlar uchun CSS da touch-events: none oârnatishni eslang.
Pointer hodisalarining qoâshimcha qobiliyatlari:
pointerIdvaisPrimaryyordamida multi-touch qoâllab-quvvatlash.- Qurilmaga xos xossalar, masalan
pressure,width/heightva boshqalar. - Pointer capturing: biz
pointerup/pointercancelgacha barcha pointer hodisalarni maâlum elementga qayta yoânaltirishimiz mumkin.
Hozirda pointer hodisalari barcha asosiy brauzerlarda qoâllab-quvvatlanadi, shuning uchun biz xavfsiz ravishda ularga oâtishimiz mumkin, ayniqsa IE10- va Safari 12- kerak boâlmasa. Va hatto oâsha brauzerlar bilan ham pointer hodisalar qoâllab-quvvatlashini yoqadigan polifilllar mavjud.
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â¦)