Biz nafaqat handlerlar belgilashimiz, balki JavaScript dan eventlar ham yaratishimiz mumkin.
Maxsus eventlar âgrafik komponentlarâ yaratish uchun ishlatilishi mumkin. Masalan, oâzimizning JS-ga asoslangan menyumizning ildiz elementi menyu bilan nima boâlayotganini bildiruvchi eventlarni ishga tushirishi mumkin: open (menyu ochish), select (element tanlash) va boshqalar. Boshqa kod eventlarni tinglashi va menyu bilan nima boâlayotganini kuzatishi mumkin.
Biz nafaqat oâz maqsadlarimiz uchun ixtiro qilgan butunlay yangi eventlarni, balki click, mousedown va boshqalar kabi oârnatilgan eventlarni ham yaratishimiz mumkin. Bu avtomatlashtirilgan test qilish uchun foydali boâlishi mumkin.
Event konstruktor
Oârnatilgan event sinflari DOM element sinflariga oâxshash ierarxiya hosil qiladi. Ildizi oârnatilgan Event sinfi.
Biz Event obyektlarini quyidagicha yaratishimiz mumkin:
let event = new Event(type[, options]);
Argumentlar:
-
type â event turi,
"click"kabi satr yoki"my-event"kabi oâzimizniki. -
options â ikkita ixtiyoriy xususiyatga ega obyekt:
bubbles: true/falseâ agartrueboâlsa, event pufaklanadi.cancelable: true/falseâ agartrueboâlsa, âstandart amalâ oldini olish mumkin. Keyinroq bu maxsus eventlar uchun nimani anglatishini koâramiz.
Standart boâyicha ikkalasi ham false:
{bubbles: false, cancelable: false}.
dispatchEvent
Event obyekti yaratilgandan keyin, uni elem.dispatchEvent(event) chaqiruvi yordamida elementda "ishga tushirish"imiz kerak.
Keyin handlerlar xuddi oddiy brauzer eventi boâlgandek unga javob beradi. Agar event bubbles bayrogâi bilan yaratilgan boâlsa, u pufaklanadi.
Quyidagi misolda click eventi JavaScript da ishga tushiriladi. Handler tugma bosilgandagi kabi ishlaydi:
<button id="elem" onclick="alert('Click!');">Autoclick</button>
<script>
let event = new Event("click");
elem.dispatchEvent(event);
</script>
âHaqiqiyâ foydalanuvchi eventini skript tomonidan yaratilgandan farqlashning usuli bor.
event.isTrusted xususiyati haqiqiy foydalanuvchi amallaridan kelgan eventlar uchun true va skript tomonidan yaratilgan eventlar uchun false.
Pufaklash misoli
Biz "hello" nomi bilan pufaklanadigan event yaratib, uni document da tutishimiz mumkin.
Bizga faqat bubbles ni true ga oârnatish kerak:
<h1 id="elem">Skriptdan salom!</h1>
<script>
// document da tutish...
document.addEventListener("hello", function(event) { // (1)
alert("Salom " + event.target.tagName + " dan"); // Salom H1 dan
});
// ...elem da jo'natish!
let event = new Event("hello", {bubbles: true}); // (2)
elem.dispatchEvent(event);
// document dagi handler faollashadi va xabarni ko'rsatadi.
</script>
Eslatmalar:
- Maxsus eventlarimiz uchun
addEventListenerdan foydalanishimiz kerak, chunkion<event>faqat oârnatilgan eventlar uchun mavjud,document.onhelloishlamaydi. bubbles:trueoârnatish kerak, aks holda event yuqoriga pufaklanmaydi.
Pufaklash mexanizmi oârnatilgan (click) va maxsus (hello) eventlar uchun bir xil. Tutish va pufaklash bosqichlari ham mavjud.
MouseEvent, KeyboardEvent va boshqalar
Mana UI Event spetsifikatsiyasi dan UI Eventlari uchun sinflarning qisqa roâyxati:
UIEventFocusEventMouseEventWheelEventKeyboardEvent- â¦
Agar biz bunday eventlarni yaratmoqchi boâlsak, new Event oârniga ulardan foydalanishimiz kerak. Masalan, new MouseEvent("click").
Toâgâri konstruktor oâsha turdagi event uchun standart xususiyatlarni belgilash imkonini beradi.
Sichqon eventi uchun clientX/clientY kabi:
let event = new MouseEvent("click", {
bubbles: true,
cancelable: true,
clientX: 100,
clientY: 100
});
alert(event.clientX); // 100
Eâtibor bering: umumiy Event konstruktor buni imkon bermaydi.
Sinab koâraylik:
let event = new Event("click", {
bubbles: true, // faqat bubbles va cancelable
cancelable: true, // Event konstruktorida ishlaydi
clientX: 100,
clientY: 100
});
alert(event.clientX); // undefined, noma'lum xususiyat e'tiborsiz qoldirildi!
Texnik jihatdan, yaratishdan keyin toâgâridan-toâgâri event.clientX=100 belgilash orqali buni hal qilishimiz mumkin. Demak, bu qulaylik va qoidalarga rioya qilish masalasi. Brauzer tomonidan yaratilgan eventlar har doim toâgâri turga ega.
Turli UI eventlari uchun xususiyatlarning toâliq roâyxati spetsifikatsiyada, masalan MouseEvent da.
Maxsus eventlar
"hello" kabi oâzimizning, butunlay yangi event turlari uchun new CustomEvent dan foydalanishimiz kerak. Texnik jihatdan CustomEvent Event bilan bir xil, bitta istisno bilan.
Ikkinchi argumentda (obyekt) biz event bilan uzatmoqchi boâlgan har qanday maxsus maâlumot uchun qoâshimcha detail xususiyatini qoâsha olamiz.
Masalan:
<h1 id="elem">John uchun salom!</h1>
<script>
// qo'shimcha tafsilotlar event bilan handlerga keladi
elem.addEventListener("hello", function(event) {
alert(event.detail.name);
});
elem.dispatchEvent(new CustomEvent("hello", {
detail: { name: "John" }
}));
</script>
detail xususiyati har qanday maâlumotga ega boâlishi mumkin. Texnik jihatdan biz busiz yashashimiz mumkin, chunki yaratilgandan keyin oddiy new Event obyektiga har qanday xususiyatlarni belgilashimiz mumkin. Ammo CustomEvent boshqa event xususiyatlari bilan ziddiyatlardan qochish uchun buning uchun maxsus detail maydonini taqdim etadi.
Bundan tashqari, event sinfi âqanday eventâ ekanligini tasvirlaydi va agar event maxsus boâlsa, bu nima ekanligini aniq koârsatish uchun CustomEvent dan foydalanishimiz kerak.
event.preventDefault()
Koâplab brauzer eventlari havolaga oâtish, tanlovni boshlash va boshqalar kabi "standart amal"ga ega.
Yangi, maxsus eventlar uchun aniq hech qanday standart brauzer amallari yoâq, lekin bunday eventni joânatuvchi kod eventni ishga tushirgandan keyin nima qilish kerakligini oâz rejalari boâlishi mumkin.
event.preventDefault() ni chaqirish orqali event handleri bu amallar bekor qilinishi kerakligi haqida signal berishi mumkin.
Bunday holatda elem.dispatchEvent(event) ga chaqiruv false qaytaradi. Va uni joânatgan kod davom etmaslik kerakligini biladi.
Keling, amaliy misolni koâraylik â yashirin quyon (yopilayotgan menyu yoki boshqa narsa boâlishi mumkin).
Quyida siz #rabbit va unga "hide" eventini joânatuvchi hide() funksiyasini koârishingiz mumkin, bu barcha manfaatdor tomonlarga quyonning yashirinishini bildiradi.
Har qanday handler oâsha eventni rabbit.addEventListener('hide',...) bilan tinglashi va kerak boâlsa event.preventDefault() yordamida amaldan voz kechishi mumkin. Shunda quyon yoâqolmaydi:
<pre id="rabbit">
|\ /|
\|_|/
/. .\
=\_Y_/=
{>o<}
</pre>
<button onclick="hide()">Hide()</button>
<script>
function hide() {
let event = new CustomEvent("hide", {
cancelable: true // bu bayroqsiz preventDefault ishlamaydi
});
if (!rabbit.dispatchEvent(event)) {
alert('Amal handler tomonidan oldini olindi');
} else {
rabbit.hidden = true;
}
}
rabbit.addEventListener('hide', function(event) {
if (confirm("preventDefault ni chaqirasizmi?")) {
event.preventDefault();
}
});
</script>
Eâtibor bering: eventda cancelable: true bayrogâi boâlishi kerak, aks holda event.preventDefault() chaqiruvi eâtiborsiz qoldiriladi.
Eventlar ichida eventlar sinxrondir
Odatda eventlar navbatda qayta ishlanadi. Yaâni: brauzer onclick ni qayta ishlayotgan boâlsa va yangi event sodir boâlsa, masalan sichqon harakatlandi, uning qayta ishlanishi navbatga qoâyiladi, tegishli mousemove handlerlari onclick qayta ishlanishi tugagandan keyin chaqiriladi.
Muhim istisno â bitta event boshqasining ichidan ishga tushirilganda, masalan dispatchEvent yordamida. Bunday eventlar darhol qayta ishlanadi: yangi event handlerlari chaqiriladi, keyin joriy event qayta ishlanishi davom etadi.
Masalan, quyidagi kodda menu-open eventi onclick paytida ishga tushiriladi.
U darhol qayta ishlanadi, onclick handlerining tugashini kutmaydi:
<button id="menu">Menu (meni bosing)</button>
<script>
menu.onclick = function() {
alert(1);
menu.dispatchEvent(new CustomEvent("menu-open", {
bubbles: true
}));
alert(2);
};
// 1 va 2 orasida ishga tushadi
document.addEventListener('menu-open', () => alert('ichki'));
</script>
Chiqish tartibi: 1 â ichki â 2.
Eâtibor bering, ichki menu-open eventi document da tutiladi. Ichki eventning tarqalishi va qayta ishlanishi tashqi kodga (onclick) qaytishdan oldin tugaydi.
Bu nafaqat dispatchEvent haqida, boshqa holatlar ham bor. Agar event handleri boshqa eventlarni ishga tushiradigan usullarni chaqirsa â ular ham sinxron tarzda, ichki koârinishda qayta ishlanadi.
Aytaylik, bu bizga yoqmaydi. Biz onclick ning avval toâliq qayta ishlanishini xohlaymiz, menu-open yoki boshqa ichki eventlardan mustaqil ravishda.
Keyin biz yoki dispatchEvent ni (yoki boshqa eventni ishga tushiruvchi chaqiruvni) onclick ning oxiriga qoâyishimiz yoki, ehtimol yaxshiroq, uni nol kechikishli setTimeout ga oârashimiz mumkin:
<button id="menu">Menu (meni bosing)</button>
<script>
menu.onclick = function() {
alert(1);
setTimeout(() => menu.dispatchEvent(new CustomEvent("menu-open", {
bubbles: true
})));
alert(2);
};
document.addEventListener('menu-open', () => alert('ichki'));
</script>
Endi dispatchEvent joriy kod bajarilishi tugagandan keyin, menu.onclick ni ham qoâshganda, asinxron tarzda ishlaydi, shuning uchun event handlerlari butunlay alohida.
Chiqish tartibi: 1 â 2 â ichki boâladi.
Xulosa
Koddan event yaratish uchun avval event obyektini yaratishimiz kerak.
Umumiy Event(name, options) konstruktor ixtiyoriy event nomi va ikkita xususiyatga ega options obyektini qabul qiladi:
bubbles: trueagar event pufaklanishi kerak boâlsa.cancelable: trueagarevent.preventDefault()ishlashi kerak boâlsa.
MouseEvent, KeyboardEvent va boshqalar kabi mahalliy eventlarning boshqa konstruktorlari oâsha event turiga xos xususiyatlarni qabul qiladi. Masalan, sichqon eventlari uchun clientX.
Maxsus eventlar uchun CustomEvent konstruktoridan foydalanishimiz kerak. Unda detail nomli qoâshimcha variant mavjud, biz eventga xos maâlumotlarni unga belgilashimiz kerak. Keyin barcha handlerlar uni event.detail sifatida olishlari mumkin.
click yoki keydown kabi brauzer eventlarini yaratishning texnik imkoniyati mavjudligiga qaramay, biz ulardan juda ehtiyotkorlik bilan foydalanishimiz kerak.
Biz brauzer eventlarini yaratmasligimiz kerak, chunki bu handlerlarni ishga tushirishning buzuq usuli. Bu koâp vaqt yomon arxitektura.
Mahalliy eventlar yaratilishi mumkin:
- Agar uchinchi tomon kutubxonalari boshqa oâzaro taâsir vositalarini taqdim etmasa, ularni kerakli tarzda ishlash uchun iflos hack sifatida.
- Avtomatlashtirilgan test qilish uchun, skriptda âtugmani bosishâ va interfeys toâgâri javob berishini koârish uchun.
Oâz nomlarimizga ega maxsus eventlar koâpincha arxitektura maqsadlari uchun yaratiladi, bizning menyularimiz, slayderlarimiz, karusellarimiz va boshqalarda nima sodir boâlayotganini bildirish uchun.
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â¦)