Maxsus hodisalar
Nafaqat brauzer, biz ham o'z maxsus hodisalarimizni (custom events) yaratib, ularni istalgan elementda ishga tushira olamiz. Bu, ayniqsa, o'z komponentlaringni yozganda foydali: komponent "tashqi dunyoga" biror voqea yuz berganini hodisa orqali xabar qiladi.
Event konstruktori
Yangi hodisa obyekti Event ichki (built-in) konstruktori orqali yaratiladi:
let event = new Event(type, options);
typeโ hodisa turi, string. Bu standart ('click') yoki o'zimiz o'ylab topgan ('my-event') bo'lishi mumkin;optionsโ ikki ixtiyoriy xossaga ega obyekt:bubbles: true/false(agartruebo'lsa, hodisa ko'tariladi) vacancelable: true/false(agartruebo'lsa, standart harakatnipreventDefault()bilan to'xtatib bo'ladi).
false: { bubbles: false, cancelable: false }. Ya'ni maxsus hodisa aytmasangiz ko'tarilmaydi va bekor qilinmaydi.dispatchEvent
Hodisa obyektini yaratgach, uni elementda "ishga tushirish" (fire) uchun elem.dispatchEvent(event) chaqiriladi. So'ng ishlovchilar go'yo bu haqiqiy brauzer hodisasidek javob beradi:
<button id="elem" onclick="alert('Klik!');">Avtoklik</button>
<script>
let event = new Event('click');
elem.dispatchEvent(event);
</script>
Bu yerda hech kim tugmani bosmasa ham, biz 'click' hodisasini dasturiy tarzda yaratib yubordik โ shuning uchun onclick ishlovchisi ishga tushadi va "Klik!" ko'rsatiladi.
event.isTrusted xossasi hodisa haqiqiy foydalanuvchi harakatidanmi (true) yoki skript orqali yaratilganmi (false) ekanini ajratadi. Skript orqali dispatchEvent qilingan hodisalarda u false bo'ladi.Maxsus hodisalar ham ko'tariladi
O'z nomi bilan hodisa yaratib, uni ko'tariladigan qilishimiz mumkin. Buning uchun bubbles: true beramiz:
<h1 id="elem">Salom, dunyodan</h1>
<script>
// hujjat darajasida maxsus 'hello' hodisasini tinglaymiz
document.addEventListener('hello', function(event) {
alert('Salom, ' + event.target.tagName); // Salom, H1
});
// ...va uni elementda ishga tushiramiz:
let event = new Event('hello', { bubbles: true });
elem.dispatchEvent(event);
</script>
Muhim jihatlar:
- Maxsus hodisalar ko'tarilishi uchun
{ bubbles: true }aniq berilishi shart; - Standart hodisalar (
click) va maxsus hodisalarni bir xil tarzda โaddEventListenerbilan tinglaymiz. Nom istalgancha bo'lishi mumkin ('hello','my-event'va hokazo).
'click') foydalanmaslik yaxshi โ chalkashlik va kutilmagan xatti-harakatlar oldini olish uchun ko'pincha o'z prefiksli nomlar (masalan, 'menu-open') ishlatiladi.CustomEvent va detail
Maxsus hodisaga qo'shimcha ma'lumot biriktirish uchun Event o'rniga maxsus CustomEvent konstruktori ishlatiladi. Uning detail degan qo'shimcha xossasi bor โ istalgan ma'lumotni shu orqali uzatamiz:
<h1 id="elem">Salom Ali uchun</h1>
<script>
elem.addEventListener('hello', function(event) {
alert(event.detail.name); // Ali
});
elem.dispatchEvent(new CustomEvent('hello', {
detail: { name: 'Ali' }
}));
</script>
detail xossasi istalgan turdagi qiymat bo'lishi mumkin: string, obyekt, massiv va hokazo. Ishlovchi ichida u event.detail orqali olinadi.
CustomEvent deyarli Event bilan bir xil, bitta farqi bor: ikkinchi argumentda detail xossasini qabul qiladi. Nima uchun oddiy Eventga o'z xossalarini qo'shmaymiz? Chunki CustomEvent nomi kodni o'qiganlarga bu maxsus hodisa ekanini va unda qanaqadir qo'shimcha ma'lumot borligini aniq bildiradi โ bu yaxshi kelishuv (konvensiya).Maxsus hodisalarni bekor qilish
Maxsus hodisalarda ham "standart harakat" tushunchasini yaratish mumkin. Buning uchun hodisani cancelable: true bilan yaratamiz, ishlovchi preventDefault() chaqirsa, dispatchEvent false qaytaradi:
<pre id="rabbit">Quyoncha</pre>
<button onclick="hide()">Yashir()</button>
<script>
function hide() {
let event = new CustomEvent('hide', {
cancelable: true // preventDefault ishlashi uchun zarur
});
if (!rabbit.dispatchEvent(event)) {
alert('Harakat ishlovchi tomonidan bekor qilindi');
} else {
rabbit.hidden = true;
}
}
rabbit.addEventListener('hide', function(event) {
if (confirm('preventDefault chaqiraymi?')) {
event.preventDefault();
}
});
</script>
Bu yerda "hide" hodisasini tinglagan kod uni bekor qila oladi. dispatchEvent agar biror ishlovchi preventDefault() chaqirgan bo'lsa false, aks holda true qaytaradi โ shu orqali harakatni davom ettirish yoki to'xtatishni hal qilamiz.
preventDefault() faqat hodisa cancelable: true bilan yaratilgan bo'lsa ishlaydi. Aks holda uni chaqirish e'tiborsiz qoldiriladi.Ichma-ich hodisalar sinxrondir
Odatda hodisalar navbatda (queue) qayta ishlanadi. Masalan, brauzer onclickni ishlab turgan payt yangi mousemove yuz bersa, uning ishlovchisi onclick tugagach chaqiriladi.
Ammo bir istisno bor: agar hodisa boshqa hodisa ichida dispatchEvent bilan ishga tushirilsa, u navbatni kutmaydi, balki darhol sinxron qayta ishlanadi. Ya'ni yangi hodisa ishlovchisi bajarilib bo'lgach, boshqaruv tashqi kodga qaytadi.
<button id="menu">Menyu (chertib ko'ring)</button>
<script>
menu.onclick = function() {
alert(1);
// menu-open hodisasi darhol (sinxron) qayta ishlanadi
menu.dispatchEvent(new CustomEvent('menu-open', { bubbles: true }));
alert(2);
};
document.addEventListener('menu-open', () => alert('ichki'));
</script>
Chiqish tartibi: 1 → ichki → 2. Ya'ni dispatchEvent ichma-ich hodisani darhol, tashqi kod davom etishidan oldin ishlab bo'ladi.
dispatchEventdan keyin nol-kechikishli setTimeout(() => elem.dispatchEvent(event), 0) ichida chaqirish mumkin โ shunda u navbatga tushib, joriy kod tugagach ishlaydi.O'z komponentlaringda maxsus hodisalar
Maxsus hodisalar mustaqil komponentlar yaratishda juda foydali. Komponent "tashqariga" o'z ichki holatidagi o'zgarishlarni maxsus hodisa orqali xabar qiladi, tashqi kod esa unga obuna bo'ladi. Bu komponentni tashqi koddan ajratib (decoupling) turadi โ komponent kim tinglayotganini bilmaydi.
// Komponent ichida (masalan, o'z galereyangiz):
function goNext(slider) {
// ... slaydni almashtiramiz ...
// tashqi dunyoga xabar beramiz:
slider.elem.dispatchEvent(new CustomEvent('slide-changed', {
bubbles: true,
detail: { index: slider.current }
}));
}
// Tashqi kod komponent ichini bilmasdan tinglaydi:
sliderElem.addEventListener('slide-changed', function(event) {
console.log('Yangi slayd: ' + event.detail.index);
});
<input> input/change hodisalarini, <video> play/pause hodisalarini yuboradi. Siz ham o'z komponentlaringni shu uslubda yozib, uni "ekotizimga" tabiiy moslashtira olasiz.Xulosa
- Maxsus hodisa
new Event(type, { bubbles, cancelable })yoki qo'shimcha ma'lumotlinew CustomEvent(type, { detail, bubbles, cancelable })bilan yaratiladi; - Uni
elem.dispatchEvent(event)orqali elementda ishga tushiramiz; bubbles: trueโ hodisa ko'tariladi;cancelable: trueโpreventDefault()orqali bekor qilinishi mumkin;- Qo'shimcha ma'lumot
CustomEventningdetailxossasida uzatiladi va ishlovchidaevent.detailorqali olinadi; dispatchEventichida ishga tushgan hodisalar sinxron qayta ishlanadi (navbatni kutmaydi);- Maxsus hodisalar mustaqil, bir-biridan ajralgan komponentlar yaratishda โ komponent tashqi dunyoga voqealarni xabar qilishida juda foydali.