Brauzer hodisalariga kirish
Hodisa (event) โ bu biror voqea sodir bo'lgani haqidagi "signal". Barcha DOM tugunlari bunday signallarni yuboradi (garchi hodisalar faqat DOM bilan cheklanmasa ham). Ushbu darsda hodisalarning umumiy tamoyillari va ularga qanday ishlov berishni chuqur o'rganamiz.
Hodisa nima?
Foydalanuvchi sahifa bilan o'zaro aloqada bo'lganda yoki brauzer ichida biror voqea yuz berganda hodisa ishga tushadi (fire/trigger). Eng ko'p uchraydigan DOM hodisalarining ba'zilari:
Sichqoncha hodisalari:
clickโ element ustida sichqoncha bosilganda (yoki sensorli ekranda tegilganda);contextmenuโ element ustida o'ng tugma bosilganda;mouseover/mouseoutโ sichqoncha element ustiga kelganda / ketganda;mousedown/mouseupโ sichqoncha tugmasi bosilganda / qo'yib yuborilganda;mousemoveโ sichqoncha harakatlanganda.
Klaviatura hodisalari:
keydown/keyupโ tugma bosilganda / qo'yib yuborilganda.
Forma elementi hodisalari:
submitโ foydalanuvchi<form>ni yuborganda;focusโ foydalanuvchi elementga (masalan,<input>ga) fokuslanganda.
Hujjat hodisalari:
DOMContentLoadedโ HTML yuklanib, DOM to'liq qurilganda.
CSS hodisalari:
transitionendโ CSS-animatsiya tugaganda.
Ishlovchi (handler) nima?
Hodisalarga ishlov berish uchun ishlovchi โ hodisa sodir bo'lganda ishlaydigan funksiya biriktiramiz. Ishlovchilar foydalanuvchi harakatiga JavaScript kodi bilan javob berishning asosiy usulidir. Ishlovchini biriktirishning bir necha yo'li bor. Ularni oddiydan murakkabga qarab ko'rib chiqamiz.
1-usul: HTML atributi (onclick)
Ishlovchini to'g'ridan-to'g'ri HTML ichida on<hodisa> ko'rinishidagi atribut bilan berish mumkin. Masalan, click hodisasi uchun onclick atributini yozamiz:
<input value="Bosing!" onclick="alert('Salom!')" type="button">
Sichqoncha bosilganda onclick ichidagi kod ishga tushadi. Atribut ichiga to'g'ridan-to'g'ri kod yozilganiga e'tibor bering โ bu yerda alert('Salom!') chaqiriladi.
onclick="...". Shu sabab ichida bitta tirnoq ishlatiladi: onclick="alert('Salom!')". Agar ikki tirnoq zarur bo'lsa, " HTML-entitisidan foydalaniladi.Kod uzun bo'lsa, uni funksiyaga o'rab, atributdan chaqirish maqsadga muvofiq:
<script>
function countRabbits() {
for (let i = 1; i <= 3; i++) {
alert('Quyoncha raqami ' + i);
}
}
</script>
<input type="button" onclick="countRabbits()" value="Quyonchalarni sana!">
ONCLICK ham, onClick ham, onclick ham ishlaydi. Lekin odatda atributlar kichik harflar bilan yoziladi: onclick.2-usul: DOM xossasi (elem.onclick)
Ishlovchini DOM xossasi on<hodisa> orqali ham biriktirish mumkin. Masalan, elem.onclickga funksiya tayinlaymiz:
<input id="elem" type="button" value="Bosing!">
<script>
elem.onclick = function() {
alert('Rahmat');
};
</script>
Endi element bosilsa, funksiya ishga tushadi. Diqqat: ishlovchi elem.onclick = ... ko'rinishida tayinlanadi, chaqirilmaydi. Ya'ni funksiyaning o'zini beramiz (nomidan keyin qavs qo'ymaymiz), uni brauzerning o'zi kerakli paytda chaqiradi.
Agar ishlovchi HTML atributi orqali berilsa, brauzer atribut mazmunidan avtomatik funksiya yaratib, uni elem.onclickga tayinlaydi. Ya'ni bu ikki usul aslida bir xil natijaga olib keladi.
onclick faqat bitta bo'la oladi
DOM xossasi orqali biriktirilganda faqat bitta ishlovchi bo'lishi mumkin. Yangi ishlovchi tayinlansa, u eskisini o'chirib tashlaydi (ustidan yozadi):
elem.onclick = function() { alert(1); };
// ...
elem.onclick = function() { alert(2); }; // eski ishlovchi almashtiriladi
// endi faqat 2 ko'rsatiladi
Ishlovchini olib tashlash uchun elem.onclick = null qilamiz.
elem.onclick = sayThanks;. Bu yerda ham funksiya nomidan keyin qavs qo'yilmaydi โ aks holda (sayThanks()) funksiyaning natijasi tayinlanadi, funksiyaning o'zi emas.3-usul: addEventListener
HTML atributi va DOM xossasining asosiy kamchiligi โ bitta hodisaga bir nechta ishlovchi biriktirib bo'lmasligi. Masalan, bir kod tugma bosilganda reklamani yoritmoqchi, boshqasi esa xabar chiqarmoqchi bo'lsa, ikkovi ham kerak. Lekin yangi onclick eskisini o'chiradi.
Shu muammoni hal qilish uchun maxsus addEventListener va removeEventListener metodlari mavjud. Ular DOM xossasining cheklovlaridan xoli va zamonaviy amaliyotda afzal ko'riladi.
Sintaksis:
element.addEventListener(event, handler, options);
eventโ hodisa nomi, masalan'click';handlerโ ishlovchi funksiya;optionsโ ixtiyoriy qo'shimcha obyekt, quyidagi xossalar bilan:once(ishlovchi bir marta ishlaydi va o'chiriladi),capture(qaysi fazada ishlashi โ keyingi darslarda),passive(ishlovchipreventDefaultni chaqirmasligini bildiradi).
elem.addEventListener('click', function() {
alert('Rahmat!');
});
Ishlovchini olib tashlash uchun removeEventListener ishlatamiz:
element.removeEventListener(event, handler, options);
// bunday qilib bo'lmaydi โ o'chirish uchun funksiyaga havola yo'q:
elem.addEventListener('click', () => alert('Rahmat!'));
// ...
elem.removeEventListener('click', () => alert('Rahmat!')); // ISHLAMAYDI
// (bu boshqa funksiya, garchi kodi bir xil bo'lsa ham)
To'g'ri yo'l โ funksiyani o'zgaruvchida saqlab, o'sha havolani uzatish:
function handler() {
alert('Rahmat!');
}
elem.addEventListener('click', handler);
// ...
elem.removeEventListener('click', handler); // endi ishlaydi
Bir nechta ishlovchi
addEventListenerning asosiy kuchi โ bir hodisaga ko'p ishlovchi biriktirish imkoni:
<input id="elem" type="button" value="Bosing!">
<script>
function handler1() {
alert('Rahmat!');
}
function handler2() {
alert('Yana rahmat!');
}
elem.onclick = () => alert('Salom');
elem.addEventListener('click', handler1); // Rahmat!
elem.addEventListener('click', handler2); // Yana rahmat!
</script>
Yuqoridagi misolda bosish natijasida uchala ishlovchi ham ishga tushadi: onclick orqali biriktirilgani va addEventListener orqali biriktirilgan ikkitasi. Ya'ni onclick va addEventListener bir-biriga xalaqit bermaydi.
addEventListener orqali biriktirish mumkin, DOM xossasi orqali emas. Masalan, DOMContentLoaded hodisasi (hujjat yuklanib, DOM tayyor bo'lganda ishga tushadi). Uning document.onDOMContentLoaded degan xossasi yo'q โ faqat document.addEventListener('DOMContentLoaded', ...) ishlaydi.Hodisa obyekti (event object)
Hodisani to'g'ri qayta ishlash uchun ko'pincha nima sodir bo'lgani haqida ko'proq ma'lumot kerak: qaysi tugma bosildi, sichqoncha koordinatalari qanaqa va hokazo. Hodisa sodir bo'lganda brauzer hodisa obyektini (event object) yaratib, uni ishlovchiga birinchi argument sifatida uzatadi.
<input type="button" value="Meni bosing" id="elem">
<script>
elem.onclick = function(event) {
// hodisa turini va elementni ko'rsatamiz
alert(event.type + ' element ' + event.currentTarget);
// sichqoncha koordinatalari
alert(event.clientX + ':' + event.clientY);
};
</script>
Hodisa obyektining eng ko'p ishlatiladigan xossalari:
event.typeโ hodisa turi, bu yerda'click';event.currentTargetโ hodisaga ishlov berayotgan element. Bu odatdathisbilan bir xil, lekin ishlovchi strelka funksiyasi (arrow) bo'lsa yokibindqilingan bo'lsa foydali;event.clientX/event.clientYโ sichqoncha hodisalari uchun kursorning oynadagi (window) koordinatalari.
event nomi bilan mavjud: <input onclick="alert(event.type)">. Brauzer atributdan funksiya yaratganda, uning birinchi argumentini event deb nomlaydi.this ishlovchi ichida
Ishlovchi ichida this โ bu ishlovchi biriktirilgan elementga havola qiladi. Quyidagi misolda tugma bosilganda o'zining valuesi (matni) ko'rsatiladi:
<button onclick="alert(this.innerHTML)">Meni bosing</button>
Bu yerda this.innerHTML โ tugmaning ichidagi matn, ya'ni 'Meni bosing'. Xuddi shu narsa DOM xossasi va addEventListener orqali biriktirilgan oddiy funksiyalarda ham ishlaydi.
thissi yo'q โ u tashqi ko'lamdan olinadi. Shuning uchun ishlovchida this orqali elementga murojaat qilmoqchi bo'lsangiz, strelka funksiya emas, oddiy funksiya ishlating. Strelka ishlatilsa, this element emas, tashqi (masalan, global) qiymat bo'ladi. Bunday holda event.currentTargetdan foydalaning.Obyekt-ishlovchi va handleEvent
addEventListener ishlovchi sifatida nafaqat funksiya, balki obyekt ham qabul qila oladi. Hodisa sodir bo'lganda, obyektning handleEvent metodi chaqiriladi:
<button id="elem">Meni bosing</button>
<script>
let obj = {
handleEvent(event) {
alert(event.type + ' element ustida ' + event.currentTarget.tagName);
}
};
elem.addEventListener('click', obj);
</script>
Ya'ni addEventListener obyekt olsa, hodisa yuz berganda uning handleEvent(event) metodini chaqiradi. Bu metod istagancha ishlovni bajarishi mumkin.
handleEvent metodi obyektning o'zida bo'lishi shart emas โ uni klass orqali ham amalga oshirish mumkin. Bu bir nechta hodisani bitta obyektda boshqarish uchun qulay:
<button id="elem">Meni bosing</button>
<script>
class Menu {
handleEvent(event) {
switch (event.type) {
case 'mousedown':
elem.innerHTML = 'Sichqoncha tugmasi bosildi';
break;
case 'mouseup':
elem.innerHTML += ' ...va qo'yib yuborildi.';
break;
}
}
}
let menu = new Menu();
elem.addEventListener('mousedown', menu);
elem.addEventListener('mouseup', menu);
</script>
Bu yerda bitta menu obyekti ikki xil hodisaga ishlov beradi. handleEvent ichida event.type orqali qaysi hodisa kelganini ajratamiz.
handleEvent metodi ishlovni to'liq o'zi bajarishi shart emas โ u faqat boshqa metodlarni chaqirishi ham mumkin. Bu hodisalarga obyektga yo'naltirilgan (OOP) usulda ishlov berish imkonini beradi.Xulosa
Ishlovchi biriktirishning uch usuli:
- HTML atributi:
onclick="..."โ kamdan-kam ishlatiladi (HTML va JS aralashib ketadi); - DOM xossasi:
elem.onclick = functionโ sodda, lekin faqat bitta ishlovchi bo'la oladi; elem.addEventListener('click', handler, options)โ eng zamonaviy va moslashuvchan usul; bir nechta ishlovchi biriktirsa bo'ladi; o'chirish uchunremoveEventListeneraynan o'sha funksiyani talab qiladi.
- Ishlovchi birinchi argument sifatida hodisa obyektini (
event) oladi. Undan hodisa turi (event.type), element (event.currentTarget) va boshqa ma'lumotlar olinadi; - Oddiy funksiya ishlovchisida
thisโ hodisa biriktirilgan elementga havola qiladi (strelka funksiyada emas); - Ishlovchi funksiya o'rniga
handleEventmetodli obyekt ham berish mumkin.