Дарси 9 · DOM ва интерфейс
Ҳодисаҳо
Саҳифае, ки танҳо маълумотро нишон медиҳад, плакат аст. Сайти зинда ҷавоб медиҳад : тугмаи «В корзину» маҳсулотро илова мекунад, майдони ҷустуҷӯ рӯйхатро фавран филтр мекунад, шакли дархост саҳифаро аз нав бор намекунад. Паси ҳар як чунин вокуниш ҳодиса истодааст. Имрӯз шумо «шунидани» кликҳо, воридкунӣ ва ирсоли шаклҳоро меомӯзед — ва рӯйхати воқеан интерактивӣ месозед, мисли барномаҳое, ки ҳар рӯз истифода мебаред.
Ба ҳодисаҳо тавассути addEventListener обуна шудан ва тавассути removeEventListener обунаро бекор кардан
Объекти ҳодисаро хондан: type, target, currentTarget, key, value
Амали пешфарзии браузерро тавассути preventDefault боздоштан (истинодҳо, шаклҳо, клавишаҳои тез)
Болоравӣ (bubbling) ва фурӯравиро (capturing) фаҳмидан ва идора кардан
Як коркардкунандаро барои бисёр элементҳо навиштан — вакилкунии ҳодисаҳо бо closest ва data-*
Хаторо барои ЗС чунон тавсиф кардан, ки ӯ аз бори аввал кӯмак расонад
Бо ин саҳифа чӣ тавр кор кардан лозим
Коди дар заминаи торик бо тугмаи ▶ Запустить — зинда аст: онро тағйир диҳед ва натиҷаро дар консол бубинед. Блокҳо бо ҷадвалҳои index.html / style.css / script.js — саҳифаҳои хурданд: дар зери код пешнамоиш пайдо мешавад, ки дар он воқеан клик кардан ва чоп кардан мумкин аст. Ишораҳои вазифаҳо пинҳон шудаанд — аввал 15 дақиқа худатон кӯшиш кунед.
Муҳим дар бораи вазифаҳо. Корбар бо муш клик мекунад, аммо санҷиши вазифаҳо худкор аст ва бояд ҳар дафъа як натиҷаи якхела диҳад. Бинобар ин дар вазифаҳо кликҳо ва воридкуниро худи код «иҷро мекунад»: button.click(), input.dispatchEvent(...). Барои коркардкунандаи шумо ин аз клики воқеӣ фарқ надорад.
01 Ҳодиса чист ва addEventListener
То даме ки шумо кодро аз боло ба поён менависед, он як маротиба иҷро мешавад ва тамом мегардад. Аммо корбар чизеро баъдтар ва ғайричашмдошт анҷом медиҳад: клик мекунад, тугмаро мезанад, матн ворид мекунад, саҳифаро варақ мезанад. Браузер ҳар як чунин амалро мушоҳида мекунад ва ҳодиса месозад — сигнали «чизе рӯй дод». Вазифаи мо — пешакӣ гуфтан: «агар чунин ҳодиса дар чунин элемент рӯй диҳад — ин функсияро иҷро кун».
Муқоиса аз ҳаёт
Дар болои дари чойхона зангӯлача овезон аст. То даме ки касе намедарояд — хомӯшӣ, пешхизмат ба кори худ банд аст. Аммо ҳамин ки дарро кушоянд — зангӯлача садо медиҳад ва пешхизмат барои истиқболи меҳмон меравад. Шумо пешакӣ мувофиқа кардед : «садо дод — ба сӯи дар рав». Ҳодиса — садои зангӯлача, коркардкунанда — амалҳои пешхизмат, ва addEventListener — худи мувофиқа.
Ҳодиса Сигнал аз браузер: click, input, submit, keydown… Ҳар ҳодиса навъ дорад — сатр бо ном.
Коркардкунанда Функсияе, ки ҳангоми рӯй додани ҳодиса иҷро мешавад. Инчунин handler ё listener («шунаванда») мегӯянд.
Обуна Пайвасти «элемент + навъи ҳодиса + функсия». Як маротиба анҷом дода мешавад, аммо ҳар қадар маротиба кор мекунад.
Обуна чӣ тавр менамояд
button .addEventListener ("click" , greet );
Кадом элементро мешунавем → «обуна шав» → ба кадом ҳодиса → чиро даъват кардан
Бигзор бо мисоли зинда бубинем. Мо тугма месозем, ба клик обуна мешавем ва тугмаро аз код бо ду даъвати click() «мезанем»:
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="buy">Купить</button>` ;
const buy = document.querySelector ("#buy" );
function onBuy () {
console.log ("Спасибо за покупку!" );
}
buy.addEventListener ("click" , onBuy);
console.log ("Обработчик навешен, клика ещё не было" );
buy.click (); // клики барномавӣ — гӯё бо муш зананд
buy.click ();
Диққат диҳед: коркардкунанда дар лаҳзаи addEventListener иҷро намешавад . Он танҳо ба ёд гирифта мешавад ва интизор мешавад. Ҳар клик онро аз нав даъват мекунад.
Воқеан кӯшиш кунед
▶ Запустить -ро пахш кунед, баъд дар пешнамоиш ба тугма клик кунед. Матни коркардкунандаро иваз кунед ё кӯшиш кунед, ки ҳисобкунак фавран ба 5 афзояд.
Ҳисобкунаки кликҳо · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< button id ="like" > ❤ Нравится</ button >
< p > Лайков: < b id ="count" > 0</ b > </ p >
button { font : inherit; padding : 8px 16px ; border-radius : 10px ; border : 1px solid #d0d5dd ; background : #fff ; cursor : pointer; }
button:active { transform : scale(.97 ); }
const like = document.querySelector ("#like" );
const count = document.querySelector ("#count" );
let likes = 0 ;
like.addEventListener ("click" , () => {
likes++;
count.textContent = likes;
console.log ("Лайков уже: " + likes);
});
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Се роҳи овехтани коркардкунанда
Роҳ Чӣ тавр менамояд Кай истифода мебаранд Атрибут дар HTML <button onclick="buy()">Истифода намебарем: аломатгузорӣ ва кодро омехта мекунад, санҷиш душвор аст Хосият btn.onclick = function () {…}Танҳо дар мисолҳои оддӣ: фақат як коркардкунандаро овехтан мумкин аст addEventListenerbtn.addEventListener("click", fn)Ҳамеша. Коркардкунандаҳо метавонанд ҳар қадар бошанд, онҳоро метавон гирифт
Фарқи асосӣ вақте намоён мешавад, ки коркардкунандаҳо якчанд мебошанд. Хосияти onclick як функсияро нигоҳ медорад — таъини навбатӣ пештараро нест мекунад. Аммо addEventListener онҳоро ба рӯйхат илова мекунад ва онҳо бо тартиби илова шудан кор мекунанд:
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="b">Кнопка</button>` ;
const b = document.querySelector ("#b" );
b.onclick = () => console.log ("onclick №1" );
b.onclick = () => console.log ("onclick №2" ); // аввалиро нест кард!
b.addEventListener ("click" , () => console.log ("слушатель №1" ));
b.addEventListener ("click" , () => console.log ("слушатель №2" ));
b.click ();
Хатои маъмул: қавсҳо баъди номи функсия
Ба addEventListener худи функсия дода мешавад, на натиҷаи даъвати он. Қавсҳои () функсияро худи ҳозир даъват мекунанд — ва коркардкунанда он чизе мегардад, ки функсия баргардонд (одатан undefined).
Хатои маъмул: функсия фавран даъват шуд, на бо клик · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="b">Кнопка</button>` ;
const b = document.querySelector ("#b" );
function hello () {
console.log ("Салом!" );
}
b.addEventListener ("click" , hello ()); // ✖ қавсҳо: «Салом!» фавран, як маротиба чоп мешавад
console.log ("Клика ещё не было, а салом уже прозвучал" );
b.click (); // аммо ба клик касе ҷавоб намедиҳад
Агар лозим бошад, ки маълумоти худро ба коркардкунанда диҳед, даъватро ба функсияи тирчадор печонед: b.addEventListener("click", () => hello("Мадина")).
Гирифтани коркардкунанда ва як маротиба кор кардан
Обунаро бекор кардан мумкин аст: removeEventListener бо ҳамон параметрҳо. Бинобар ин функсияро дар тағйирёбанда нигоҳ доштан лозим аст — тирчаи беном-ро гирифтан намешавад, зеро он функсияи «дигар» мебошад.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="b">Талон</button>` ;
const b = document.querySelector ("#b" );
function takeTicket () {
console.log ("Ваш талон выдан" );
b.removeEventListener ("click" , takeTicket); // ҳамон элемент, навъ ва функсия
}
b.addEventListener ("click" , takeTicket);
b.click ();
b.click (); // хомӯшӣ — коркардкунанда гирифта шуд
console.log ("Второй клик ничего не сделал" );
Барои ҳолати «як маротиба кор кардан» роҳи кӯтоҳ ҳаст — аргументи сеюм бо танзимот. Браузер худаш коркардкунандаро баъди аввалин кор кардан мегирад:
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="b">Приз</button>` ;
const b = document.querySelector ("#b" );
b.addEventListener ("click" , () => console.log ("Вы получили приз!" ), { once: true });
b.click ();
b.click ();
b.click ();
Барои муфассалтар хондан: learn.javascript.ru — Введение в браузерные события · MDN — addEventListener
Амалиёт: мустаҳкам мекунем
Дар ҳамаи вазифаҳо тугмаро код «мезанад» — шумо бояд коркардкунанда нависед.
ВАЗИФАИ 1.1 Зангӯлача дар чойхона осон
Дар болои дари чойхона зангӯлача овезон аст — тугмаи #bell. Ба клики он чунон обуна шавед, ки ҳар дафъа «Динь-динь!» чоп шавад. Се меҳмон даромад — се садо.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="bell">Дверь</button>` ;
const bell = document.querySelector ("#bell" );
// коди шумо инҷо
bell.click ();
bell.click ();
bell.click ();
Натиҷаи интизоршаванда Динь-динь!
Динь-динь!
Динь-динь!
Ишора 1 Усули bell.addEventListener(навъ, функсия) лозим аст. Навъи ҳодиса — сатри "click".
Ишора 2 bell.addEventListener("click", () => { console.log("…"); }); — функсияи тирчадор бевосита дар аргумент.
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 1.2 Хаторо ёб: салом пеш аз вақт осон
Интизор мерафт, ки «Салом, Мадина!» ду маротиба — барои ҳар клик як маротиба ва баъди сатри «Кнопка готова» чоп шавад. Ҳоло ҳама чиз дигар аст: як хаторо ёбед ва ислоҳ кунед.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="hi">Поздороваться</button>` ;
const hi = document.querySelector ("#hi" );
function sayHello () {
console.log ("Салом, Мадина!" );
}
hi.addEventListener ("click" , sayHello ());
console.log ("Кнопка готова" );
hi.click ();
hi.click ();
Натиҷаи интизоршаванда Кнопка готова
Салом, Мадина!
Салом, Мадина!
Ишора 1 Онро чун ҳаст иҷро кунед ва ба тартиби сатрҳо нигоҳ кунед: салом пеш аз клик пайдо шуд. Пас функсия дар лаҳзаи обуна даъват шудааст.
Ишора 2 Қавсҳои гирдро баъди sayHello дар addEventListener нест кунед: браузер худаш функсияро ҳангоми клик даъват мекунад.
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 1.3 Тартибро пешгӯӣ кун осон
Инак чор коркардкунанда дар як тугма. Яке аз онҳо дигареро нест мекунад. Дар массиви prediction нависед, ки баъди як клик кадом ҳарфҳо ва бо кадом тартиб ба actual меафтанд. Кодро фавран иҷро накунед — аввал фикр кунед. Ҷавоб ба экран чоп намешавад: консол танҳо хабар медиҳад, ки шумо дуруст пешгӯӣ кардед ё не.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="b">Кнопка</button>` ;
const b = document.querySelector ("#b" );
const actual = [];
b.onclick = () => actual.push ("A" );
b.onclick = () => actual.push ("B" );
b.addEventListener ("click" , () => actual.push ("C" ));
b.addEventListener ("click" , () => actual.push ("D" ));
b.click ();
const prediction = []; // ҳарфҳоро дар сатрҳо нависед, масалан ["X", "Y"]
console.log (prediction.join (" " ) === actual.join (" " ) ? "Прогноз верный" : "Прогноз неверный" );
Натиҷаи интизоршаванда Прогноз верный
Ишора 1 Таъини дуюми b.onclick = … бо аввалин чӣ мекунад? Оё дар ин «ҷой» як функсия мемонад?
Ишора 2 Барои санҷиши худ, console.log(actual.join(" "))-ро муваққатан пеш аз сатри охирин илова кунед. Аммо аввал пешгӯӣ кунед!
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 1.4 Ҳадди кликҳо миёна
Акция: танҳо се клики аввал «таҳфиф» мегиранд. Коркардкунандаи onClick-ро ба итмом расонед: он ҳисобкунакро зиёд мекунад, «Клик 1», «Клик 2», «Клик 3» чоп мекунад, ва дар клики сеюм иловатан «Лимит исчерпан, обработчик снят» чоп мекунад ва худро мегирад . Минбаъд тугма хомӯш аст (код онро панҷ маротиба мезанад).
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="promo">Скидка</button>` ;
const promo = document.querySelector ("#promo" );
let count = 0 ;
function onClick () {
// коди шумо инҷо
}
promo.addEventListener ("click" , onClick);
for (let i = 0 ; i < 5 ; i++) {
promo.click ();
}
Натиҷаи интизоршаванда Клик 1
Клик 2
Клик 3
Лимит исчерпан, обработчик снят
Ишора 1 Дар дохили функсия: count++, баъд console.log("Клик " + count), баъд if (count === 3) { … }.
Ишора 2 Гирифтани коркардкунанда: promo.removeEventListener("click", onClick); — функсия дар мо дар тағйирёбанда бо номи onClick аст, бинобар ин гирифтани он мумкин аст.
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
02 Объекти ҳодиса
Вақте браузер коркардкунандаи шуморо даъват мекунад, ба он як аргумент — объекти ҳодисаро медиҳад. Одатан онро event, evt ё мухтасар e меноманд. Дар он ҳама чизе, ки дар бораи рӯйдод маълум аст, ҷой дорад: аз кадом навъ аст, дар кадом элемент рӯй дод, муш дар куҷо буд, кадом клавиша зада шуд.
Муқоиса аз ҳаёт
Диспетчери маршрутка дар журнал сабт мекунад: «чӣ шуд (савор шудан), дар куҷо (бекати «Шохмансур»), соати чанд , кӣ савор шуд». Объекти ҳодиса — ҳамин гуна варақаи журнал аст. Агар хоҳед тафсилотро бидонед — ба он нигоҳ кунед.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="pay" class="btn">Оплатить</button>` ;
const pay = document.querySelector ("#pay" );
pay.addEventListener ("click" , (event) => {
console.log ("Тип события:" , event.type);
console.log ("Элемент:" , event.target.id);
console.log ("Тег:" , event.target.tagName);
console.log ("Это Event?" , event instanceof Event);
});
pay.click ();
Хосиятҳои аз ҳама муфид
Хосият Чӣ медиҳад Мисол event.typeНавъи ҳодиса ба шакли сатр "click", "input"event.targetЭлементе, ки дар он ҳодиса рух дод Тугма ё нишона дар дохили он event.currentTargetЭлементе, ки коркардкунандаи шумо дар он овезон аст Ҳамон, ки барои он addEventListener даъват шуд event.clientX / clientYКоординатаҳои муш дар тиреза (дар ҳодисаҳои муш) 120, 45event.keyКадом клавиша зада шуд (дар ҳодисаҳои клавиатура) "Enter", "a", "Escape"event.target.valueМатн дар майдони воридкунӣ (дар input) "Душанбе"event.preventDefault()Бекор кардани амали пешфарзии браузер Бахши 04
Муш ва клавиатура
«Тугмаро задан»-ро аз код чӣ тавр иҷро кардан мумкин? Ҳодисаро дастӣ месозем ва бо усули dispatchEvent ба элемент мефиристем. Мо дар вазифаҳо ҳамин тавр амал мекунем — барои коркардкунандаи шумо ин ба задани воқеӣ монанд аст.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<input id="field" placeholder="Введите имя">` ;
const field = document.querySelector ("#field" );
field.addEventListener ("keydown" , (e) => {
console.log ("Нажата клавиша:" , e.key);
});
field.dispatchEvent (new KeyboardEvent ("keydown" , { key: "Enter" }));
field.dispatchEvent (new KeyboardEvent ("keydown" , { key: "a" }));
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<div id="map" style="width:300px;height:200px">Карта</div>` ;
const map = document.querySelector ("#map" );
map.addEventListener ("click" , (e) => {
console.log (`Клик в точке (${e.clientX}, ${e.clientY})` );
});
map.dispatchEvent (new MouseEvent ("click" , { clientX: 120 , clientY: 45 }));
target ва currentTarget: кӣ кор кард ва кӣ мешунавад
Ин ду хосияти гуногун аст ва омехтакунии онҳо яке аз маъмултарин хатоҳост. Бигзор дар дохили тугма нишонаи <b> бошад. Агар ба нишона клик кунанд, пас:
target Элементи аз ҳама чуқур, ки ба он воқеан клик карданд: нишонаи <b>.
currentTarget Элементе, ки барои он коркардкунанда даъват шудааст : тугма. Ҳамеша ҳамон, ки шумо барояш addEventListener навиштаед.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="cart"><b id="icon">🛒</b> Корзина</button>` ;
const cart = document.querySelector ("#cart" );
const icon = document.querySelector ("#icon" );
cart.addEventListener ("click" , (e) => {
console.log ("target:" , e.target.tagName);
console.log ("currentTarget:" , e.currentTarget.tagName);
});
icon.click (); // ба нишона дар дохили тугма клик карданд
cart.click (); // ба худи тугма клик карданд
То даме ки элемент як аст, онҳо мувофиқат мекунанд. Аммо ҳамин ки дар дохил элементҳои дарунмонда ҳастанд, target метавонад «чуқуртар» шавад. Ин муҳим аст: дар бахши 06 мо дар ин асос як техникаи томро месозем.
Аммо this чист?
Дар функсияи оддии коркардкунанда this низ ба элементе ишора мекунад, ки коркардкунанда дар он овезон аст — ҳамон ки currentTarget. Дар функсияи тирчадор this дигар аст. Барои ҳадс назадан, ҳамеша event.currentTarget-ро истифода баред — он дар ҳама ҷо яксон кор мекунад.
Хатои маъмул: хосият на аз ҳамон ҳодиса
Маҷмӯи хосиятҳо аз навъи ҳодиса вобаста аст. Клик клавиша надорад, зеро пахши клавиша координатаҳои муш надорад. JavaScript хафа намешавад — он танҳо undefined бармегардонад ва шумо ним соат барои ҷустуҷӯи «хато» сарф мекунед.
Хатои маъмул: клик хосияти key надорад · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="b">Кнопка</button>` ;
const b = document.querySelector ("#b" );
b.addEventListener ("click" , (e) => {
console.log (e.key); // undefined — клик клавиша надорад
console.log (e.clientX); // аммо координатаҳо ҳастанд (0, зеро клик барномавӣ аст)
});
b.click ();
Агар шубҳа дошта бошед, ки ҳодиса кадом хосиятҳоро дорад, тамоми объектро чоп кунед: console.log(e) — ва дар DevTools нигоҳ кунед.
Барои муфассалтар хондан: learn.javascript.ru — Объект события · MDN — Event.currentTarget · MDN — KeyboardEvent.key
Амалиёт: мустаҳкам мекунем
ВАЗИФАИ 2.1 Шиносномаи ҳодиса осон
Коркардкунандаи клики тугмаи #pay-ро ба итмом расонед: он се сатр чоп мекунад — навъи ҳодиса, id-и элементи сарчашма ва номи тегаш. Формат — мисли натиҷаи интизоршаванда.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="pay">Оплатить</button>` ;
const pay = document.querySelector ("#pay" );
pay.addEventListener ("click" , (event) => {
// коди шумо инҷо
});
pay.click ();
Натиҷаи интизоршаванда Событие: click
Элемент: pay
Тег: BUTTON
Ишора 1 Навъ — event.type, элемент — event.target, он хосиятҳои id ва tagName дорад.
Ишора 2 Сатри қолабӣ: console.log(`Событие: ${event.type}`); — се чунин даъват.
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 2.2 Вокуниш ба клавишаҳо миёна
Дар майдони #msg се клавиша «зада мешавад». Коркардкунандаи keydown бояд чунин вокуниш кунад: Enter → «Отправка», Escape → «Очистка», ҳама дигар → «Нажата клавиша: » ва номи он.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<input id="msg">` ;
const msg = document.querySelector ("#msg" );
// коди шумо инҷо
for (const key of ["a" , "Enter" , "Escape" ]) {
msg.dispatchEvent (new KeyboardEvent ("keydown" , { key }));
}
Натиҷаи интизоршаванда Нажата клавиша: a
Отправка
Очистка
Ишора 1 Номи клавиша — event.key. Ҳолатҳоро бо if … else if … else ҷудо кардан қулай аст.
Ишора 2 if (event.key === "Enter") { … } else if (event.key === "Escape") { … } else { console.log("Нажата клавиша: " + event.key); }
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 2.3 Кӣ кор кард ва кӣ мешунавад миёна
Дар тугмаи #order нишонаи <b id="icon"> ҷой дорад. Ба клик дар тугма обуна шавед ва ду сатр чоп кунед: тегҳои target ва currentTarget. Код ду маротиба «клик мекунад»: аввал ба нишона, баъд ба тугма. Муқоиса кунед, чӣ тағйир ёфт.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<button id="order"><b id="icon">🚕</b> Заказать такси</button>` ;
const order = document.querySelector ("#order" );
const icon = document.querySelector ("#icon" );
// коди шумо инҷо: коркардкунанда дар order
icon.click ();
console.log ("---" );
order.click ();
Натиҷаи интизоршаванда target: B
currentTarget: BUTTON
---
target: BUTTON
currentTarget: BUTTON
Ишора 1 Коркардкунанда ба order овехта мешавад — на ба icon. Клик ба нишона худаш ба тугма «боло мебарояд», дар ин бора муфассал дар бахши 05.
Ишора 2 order.addEventListener("click", (e) => { console.log("target: " + e.target.tagName); console.log("currentTarget: " + e.currentTarget.tagName); });
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
03 Кадом ҳодисаҳо ҳастанд
Ҳодисаҳо дар браузер даҳҳо ҳастанд, аммо дар кори ҳаррӯза шумо панҷ-ҳафтои онро истифода мебаред. Инак онҳое, ки дар ҳар лоиҳаи дуюм вомехӯранд:
Ҳодиса Кай кор мекунад Дар куҷо истифода мебаранд clickКлики муш, ламси ангушт, Enter дар тугма Тугмаҳо, корточкаҳо, меню dblclick, contextmenuКлики дучанда, тугмаи рости муш Таҳрир бо клики дучанда, менюи худӣ mouseover / mouseoutМуш ба элемент даромад / аз он баромад Ишораҳо, равшан кардан keydown / keyupКлавиша зада шуд / раҳо шуд Клавишаҳои тез, Enter, Escape inputҲар тағйири матн дар майдонҶустуҷӯи зинда, ҳисобкунаки аломатҳо changeҚимат «собит шуд»: банд интихоб шуд, нишона гузошта шуд, аз майдон баромаданд Select, checkbox, radio focus / blurМайдон фокус гирифт / аз даст дод Равшан кардани майдон, санҷиш ҳангоми баромадан submitШакл фиристода мешавад (тугма ё Enter) Ҳама шаклҳо — дархостҳо, вуруд, ҷустуҷӯ DOMContentLoadedHTML пурра хонда ва сохта шуд Оғози скрипте, ки дар <head> пайваст шудааст
Муқоиса аз ҳаёт
Шумо дар Telegram паём менависед. Ҳодисаи input — ин «ҳамсӯҳбат чоп мекунад…»: он барои ҳар ҳарф меояд. Аммо change — ин «паём фиристода шуд»: як маротиба меояд, вақте шумо тамом кардед. Барои ҷустуҷӯи зинда input лозим аст, барои интихоби шаҳр аз рӯйхат — change.
input: қимати майдон барои ҳар ҳарф
Матнро аз майдон тавассути event.target.value (ё input.value) мехонем. Ин ҳамеша сатр аст, ҳатто агар корбар рақам ворид карда бошад. Барои тақлиди воридкунӣ дар код, value-ро мегузорем ва ҳодисаи input-ро мефиристем:
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<input id="name">` ;
const name = document.querySelector ("#name" );
name.addEventListener ("input" , (e) => {
console.log ("Сейчас в поле:" , e.target.value);
});
for (const text of ["Ф" , "Фа" , "Фар" , "Фарход" ]) {
name.value = text;
name.dispatchEvent (new Event ("input" ));
}
change, checkbox ва select
Дар байрақча checked-ро мехонем (true/false), дар рӯйхати кушодашаванда — value-и банди интихобшударо:
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<label><input type="checkbox" id="sugar"> С сахаром</label>
<select id="tea"><option>Чёрный</option><option>Зелёный</option></select>` ;
const sugar = document.querySelector ("#sugar" );
const tea = document.querySelector ("#tea" );
sugar.addEventListener ("change" , (e) => console.log ("Сахар:" , e.target.checked));
tea.addEventListener ("change" , (e) => console.log ("Чай:" , e.target.value));
sugar.checked = true ;
sugar.dispatchEvent (new Event ("change" ));
tea.value = "Зелёный" ;
tea.dispatchEvent (new Event ("change" ));
Мисоли зинда: ҷустуҷӯ ва ҳисобкунак
▶ Запустить -ро пахш кунед ва дар майдон чоп кунед. Рӯйхат барои ҳар ҳарф филтр мешавад — ин ҳодисаи input дар шакли холис аст.
Ҷустуҷӯи зинда аз рӯи шаҳрҳо · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< input id ="search" placeholder ="Найти город…" >
< small id ="info" > Введите хотя бы букву</ small >
< ul id ="cities" >
< li > Душанбе</ li > < li > Худжанд</ li > < li > Бохтар</ li >
< li > Куляб</ li > < li > Истаравшан</ li > < li > Хорог</ li >
</ ul >
input { font : inherit; padding : 8px 12px ; border : 1px solid #d0d5dd ; border-radius : 10px ; }
small { margin-left : 8px ; color : #667085 ; }
li { padding : 2px 0 ; }
const search = document.querySelector ("#search" );
const info = document.querySelector ("#info" );
const items = document.querySelectorAll ("#cities li" );
search.addEventListener ("input" , (event) => {
const query = event.target.value.trim ().toLowerCase ();
let shown = 0 ;
items.forEach ((li) => {
const match = li.textContent.toLowerCase ().includes (query);
li.hidden = !match; // номувофиқонро пинҳон мекунем
if (match) shown++;
});
info.textContent = `Символов: ${query.length}, найдено: ${shown}` ;
console.log (`Запрос «${query}» → ${shown}` );
});
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Хатои маъмул: input ва change-ро дар майдони матнӣ омехта мекунанд
Дар майдони матнӣ change танҳо вақте кор мекунад, ки шумо аз майдон баромадед ё Enter-ро заданд. Агар ба он ҷустуҷӯи зиндаро овезед, натиҷа «бо таъхир» пайдо мешавад — ва корбар фикр мекунад, ки сайт овезон мешавад. Барои ҷустуҷӯ ва ҳисобкунакҳо input-ро гиред.
Барои муфассалтар хондан: learn.javascript.ru — Клавиатура: keydown и keyup · MDN — Справочник событий
Амалиёт: мустаҳкам мекунем
ВАЗИФАИ 3.1 Ҳисобкунаки аломатҳо осон
Барои майдони «О себе» ҳисобкунак созед, мисли анкетаи MakeFirstStep. Барои ҳар ҳодисаи input сатри «Символов: N»-ро чоп кунед, ки N — дарозии матн дар майдон аст.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<textarea id="about"></textarea>` ;
const about = document.querySelector ("#about" );
// коди шумо инҷо
for (const text of ["Привет" , "Привет, Душанбе" ]) {
about.value = text;
about.dispatchEvent (new Event ("input" ));
}
Натиҷаи интизоршаванда Символов: 6
Символов: 15
Ишора 1 Матн аз майдон — event.target.value. Ин сатр аст, сатрҳо хосияти length доранд.
Ишора 2 about.addEventListener("input", (e) => console.log("Символов: " + e.target.value.length));
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 3.2 Ҷустуҷӯи шаҳр дар ҳамон лаҳза миёна
Барои ҳар ҳодисаи input дар майдони #q аз массиви cities шаҳрҳоеро ёбед, ки дар номашон матни воридшуда ҳаст (бе ҳисоби регистр, холигоҳҳои ҳошияҳоро нест кунед). «Запрос «текст»: »-ро ва шаҳрҳоро бо вергул чоп кунед. Агар чизе ёфт нашавад — «ничего не найдено». Дар натиҷа дархост ҳамон тавр навишта мешавад, ки корбар ворид кард, аммо бе холигоҳҳо дар ҳошияҳо.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<input id="q">` ;
const q = document.querySelector ("#q" );
const cities = ["Душанбе" , "Худжанд" , "Бохтар" , "Куляб" , "Истаравшан" , "Хорог" ];
// коди шумо инҷо
for (const text of ["ху" , " ХО " , "а" , "щ" ]) {
q.value = text;
q.dispatchEvent (new Event ("input" ));
}
Натиҷаи интизоршаванда Запрос «ху»: Худжанд
Запрос «ХО»: Хорог
Запрос «а»: Душанбе, Худжанд, Бохтар, Истаравшан
Запрос «щ»: ничего не найдено
Ишора 1 Аввал дархостро ба тартиб оред: const query = e.target.value.trim();. Барои муқоиса query.toLowerCase() ва city.toLowerCase().includes(…)-ро истифода баред, аммо чоп кунед — query-и аслиро.
Ишора 2 const found = cities.filter(c => c.toLowerCase().includes(query.toLowerCase())); Баъд found.length ? found.join(", ") : "ничего не найдено".
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 3.3 Нархи ниҳоӣ бо расонидан миёна
Маҳсулот 100 сомонӣ меарзад. Расонидан пулакӣ аст, агар нишонаи #delivery гузошта шуда бошад: ба Душанбе 10 сомонӣ, ба Хуҷанд 25. Функсияи recalc-ро нависед, ки «Итого: N сомони»-ро чоп мекунад, ва онро ба change ҳам дар рӯйхати шаҳрҳо, ҳам дар байрақча обуна кунед. Коди зерин худаш қиматҳоро чор маротиба «тағйир медиҳад».
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<select id="city"><option>Душанбе</option><option>Худжанд</option></select>
<label><input type="checkbox" id="delivery"> Доставка</label>` ;
const city = document.querySelector ("#city" );
const delivery = document.querySelector ("#delivery" );
const price = 100 ;
const fees = { "Душанбе" : 10 , "Худжанд" : 25 };
function recalc () {
// коди шумо инҷо: ҳисоб кардан ва чоп кардани «Итого: N сомони»
}
// коди шумо инҷо: обунаҳо ба change
const fire = (el) => el.dispatchEvent (new Event ("change" ));
city.value = "Худжанд" ; fire (city);
delivery.checked = true ; fire (delivery);
city.value = "Душанбе" ; fire (city);
delivery.checked = false ; fire (delivery);
Натиҷаи интизоршаванда Итого: 100 сомони
Итого: 125 сомони
Итого: 110 сомони
Итого: 100 сомони
Ишора 1 Дар дохили recalc ҳолати ҷориро бевосита аз элементҳо хонед: city.value ва delivery.checked. Арзиши расонидан — fees[city.value].
Ишора 2 const total = price + (delivery.checked ? fees[city.value] : 0); Обуна: city.addEventListener("change", recalc); ва ҳамин гуна барои delivery. Баъди recalc қавс нест!
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
04 Амали пешфарз: preventDefault
Барои бисёр ҳодисаҳо браузер амали пешфарзии худро дорад. Он баъд аз коркардкунандаҳои шумо иҷро мешавад, агар онро боз надоред:
клик ба истинод <a href> — гузариш ба саҳифаи дигар;
ирсоли шакл — аз нав бор шудани саҳифа бо маълумот;
клики тугмаи рости муш — менюи контекстӣ;
Ctrl + S — тирезаи «Захира кардани саҳифа»;
фосила дар саҳифа — варақ задан ба поён.
Усули event.preventDefault() ба браузер мегӯяд: «Лозим нест, минбаъд худам». Коди шумо дар ин ҳол мисли пештара кор карда истодааст.
Муқоиса аз ҳаёт
Шумо ба турникети истгоҳ наздик мешавед ва назоратчӣ мегӯяд: «Истед, аввал чиптаро нишон диҳед». Шумо мехостед гузаред (амали пешфарз), аммо шуморо боздоштанд — ва акнун шумо қарор медиҳед, ки иҷозат диҳед ё не. preventDefault — дасти боло кардаи назоратчӣ: гузариш бекор шуд, аммо боқии корҳо дар толор ба тартиби худ идома меёбанд.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<a id="promo" href="https://example.com/promo">Акция недели</a>` ;
const promo = document.querySelector ("#promo" );
promo.addEventListener ("click" , (e) => {
e.preventDefault (); // дар саҳифа мемонем
console.log ("Переход отменён:" , e.defaultPrevented);
});
promo.click ();
Ҳолати асосӣ: шакл
Ирсоли шакл ба таври пешфарз саҳифаро аз нав бор мекунад : ҳар чизе ки JavaScript кашида буд, нест мешавад. Бинобар ин қариб ҳар шакл дар сайти муосир чунин коркард мешавад: submit-и шаклро мешунавем (на click-и тугмаро!), preventDefault()-ро иҷро мекунем ва бо маълумот худамон кор мекунем.
Чаро маҳз submit, на клик ба тугма? Шаклро бо клавишаи Enter дар майдон фиристодан мумкин аст — клик ба тугма дар ин ҳолат рух намедиҳад, аммо submit ҳамеша кор мекунад. Дар вазифаҳои мо шаклро код «мефиристад»: он ҳодисаи submit-ро бо фармони form.dispatchEvent(new Event("submit", { cancelable: true })) дастӣ пеш мебарад. Коркардкунанда фарқиятро намебинад, ва саҳифа аз нав бор намешавад.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<form id="order">
<input id="who" value="Мадина">
<button>Заказать</button>
</form>` ;
const order = document.querySelector ("#order" );
const who = document.querySelector ("#who" );
order.addEventListener ("submit" , (e) => {
e.preventDefault (); // бе ин сатр саҳифа аз нав бор мешуд
console.log ("Заказ для:" , who.value);
});
order.dispatchEvent (new Event ("submit" , { cancelable: true }));
who.value = "Фарход" ;
order.dispatchEvent (new Event ("submit" , { cancelable: true }));
Худатон кӯшиш кунед
▶ Запустить -ро пахш кунед, ном ворид кунед ва Enter ё тугмаро пахш кунед. Саҳифа аз нав бор намешавад, ном ба рӯйхат илова мешавад — ин кори preventDefault аст.
Шакл бе аз нав бор шудан · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< form id ="join" >
< input id ="who" placeholder ="Ваше имя" autocomplete ="off" >
< button > Записаться</ button >
</ form >
< ol id ="people" > </ ol >
input, button { font : inherit; padding : 8px 12px ; border-radius : 10px ; border : 1px solid #d0d5dd ; }
button { background : #fff ; cursor : pointer; }
const join = document.querySelector ("#join" );
const who = document.querySelector ("#who" );
const people = document.querySelector ("#people" );
join.addEventListener ("submit" , (event) => {
event.preventDefault ();
const name = who.value.trim ();
if (name === "" ) return ; // номи холиро илова намекунем
const li = document.createElement ("li" );
li.textContent = name;
people.append (li);
who.value = "" ;
console.log ("Записано человек:" , people.children.length);
});
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Бо stopPropagation омехта накунед
preventDefault()stopPropagation()Чиро боз медорад Амали браузер (гузариш, ирсол…) Роҳи минбаъдаи ҳодиса ба боло аз рӯи элементҳо Коркардкунандаҳои дигар Кор карданро давом медиҳанд Дар болои занҷир даъват намешаванд Муфассалтар дар бораи чӣ Ин бахш Бахши 05
Хатои маъмул: preventDefault «кор накард»
Ду сабаби маъмул. Аввал — шумо коркардкунандаро ба click-и тугма овехтаед, дар ҳоле ки шаклро бо клавишаи Enter ҳам мефиристанд: submit-ро бишнавед. Дуюм — preventDefault на дар ҳама шоха даъват шудааст: масалан, дар дохили if, ва ҳангоми хатои санҷиш пештар return кор кард. Аввал амалро бекор кунед, баъд санҷед.
Хатои маъмул: бекор кардан танҳо дар як шоха · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<form id="f"><input id="i"></form>` ;
const f = document.querySelector ("#f" );
const i = document.querySelector ("#i" );
f.addEventListener ("submit" , (e) => {
if (i.value === "" ) {
console.log ("Пусто!" );
return ; // ✖ баромадем, бе бекор кардани ирсол
}
e.preventDefault ();
console.log ("Отправка" , i.value);
});
// ирсоли шакли холиро тақлид мекунем ва мебинем, ки амали браузерро бекор кардем ё не
const ev = new Event ("submit" , { cancelable: true });
f.dispatchEvent (ev);
console.log ("Перезагрузка отменена?" , ev.defaultPrevented);
Барои муфассалтар хондан: learn.javascript.ru — Действия браузера по умолчанию · MDN — Event.preventDefault
Амалиёт: мустаҳкам мекунем
ВАЗИФАИ 4.1 Истиноди дом осон
Истиноди #promo ба сайти беруна мебарад, аммо мо мехоҳем дар саҳифа бимонем. Ба клик обуна шавед, гузаришро бекор кунед ва ду сатр чоп кунед: «Переход отменён» ва қимати event.defaultPrevented (он бояд true бошад).
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<a id="promo" href="https://example.com">Скидки</a>` ;
const promo = document.querySelector ("#promo" );
// коди шумо инҷо
promo.click ();
Натиҷаи интизоршаванда Переход отменён
true
Ишора 1 Коркардкунандаи клик event-ро мегирад. Усули бекор кардан — event.preventDefault().
Ишора 2 Аввал preventDefault()-ро иҷро кунед, баъд console.log("Переход отменён") ва console.log(event.defaultPrevented)-ро чоп кунед.
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 4.2 Шакли дархост миёна
Коркардкунандаи submit-ро барои шакли дархости курс нависед. Он аз нав бор шуданро бекор мекунад ва номро месанҷад: агар майдони #name холӣ бошад (баъди trim()) — «Введите имя» чоп мекунад, вагарна — «Заявка: имя, телефон». Коди зерин шаклро ду маротиба мефиристад.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<form id="apply">
<input id="name">
<input id="phone">
<button>Отправить</button>
</form>` ;
const apply = document.querySelector ("#apply" );
const nameInput = document.querySelector ("#name" );
const phoneInput = document.querySelector ("#phone" );
// коди шумо инҷо
nameInput.value = "Мадина" ;
phoneInput.value = "900 11 22 33" ;
apply.dispatchEvent (new Event ("submit" , { cancelable: true }));
nameInput.value = " " ;
apply.dispatchEvent (new Event ("submit" , { cancelable: true }));
Натиҷаи интизоршаванда Заявка: Мадина, 900 11 22 33
Введите имя
Ишора 1 submit-и шакли apply-ро бишнавед, на клики тугмаро. Сатри аввали коркардкунанда — event.preventDefault().
Ишора 2 const name = nameInput.value.trim(); Баъд if (name === "") { console.log("Введите имя"); return; } ва чопи дархост бо сатри қолабӣ.
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 4.3 Клавишаҳои тези муҳаррир душвор
Шумо муҳаррири онлайн месозед. Ба keydown-и document обуна шавед ва омезишҳоро коркард кунед: Ctrl + S → «Сохранено», Ctrl + Shift + S → «Сохранить как…», Ctrl + Z → «Отмена». Ин омезишҳо амали пешфарзии браузерро доранд — онро бояд бекор кард . Клавишаҳои дигар (масалан, танҳо a)-ро намерасонем. Ишора: ҳангоми зада будани Shift ҳарф дар event.key бо ҳарфи калон меояд.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
const press = (key, ctrl, shift) => {
const ev = new KeyboardEvent ("keydown" , { key, ctrlKey: ctrl, shiftKey: shift, bubbles: true , cancelable: true });
document.dispatchEvent (ev);
const label = (ctrl ? "Ctrl + " : "" ) + (shift ? "Shift + " : "" ) + key;
console.log (`${label}: действие по умолчанию ${ev.defaultPrevented ? "отменено" : "работает"}` );
};
// коди шумо инҷо: обуна ба keydown дар document
press ("s" , true , false );
press ("S" , true , true );
press ("a" , false , false );
press ("z" , true , false );
Натиҷаи интизоршаванда Сохранено
Ctrl + s: действие по умолчанию отменено
Сохранить как…
Ctrl + Shift + S: действие по умолчанию отменено
a: действие по умолчанию работает
Отмена
Ctrl + z: действие по умолчанию отменено
Ишора 1 Ҳодиса хосиятҳои булии event.ctrlKey ва event.shiftKey-ро дорад. Клавишаро ба як регистр оред: const key = event.key.toLowerCase();.
Ишора 2 Аввал «борик»-тарин омезишро санҷед: if (event.ctrlKey && event.shiftKey && key === "s") { … } else if (event.ctrlKey && key === "s") { … } else if (event.ctrlKey && key === "z") { … }. Дар ҳар шоха — event.preventDefault().
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
05 Болоравӣ ва фурӯравӣ
Агар тугма дар дохили корточка бошад, корточка дар дохили рӯйхат, ва дар ҳар як аз онҳо коркардкунандаи клики худӣ овезон бошад, чӣ мешавад? Ҳар се кор мекунанд — ва бо тартиби хеле муайян. Ҳодиса дар элементе, ки ба он клик карданд, «намеистад»: он дар занҷири падарон сайр мекунад .
<ul id="list"> — коркардкунандаи №3
<li class="card"> — коркардкунандаи №2
<button> — коркардкунандаи №1 (инҷо клик карданд)
1. фурӯравӣ ↓ аз боло ба поён 2. ҳадаф: button 3. болоравӣ ↑ аз поён ба боло
Се марҳилаи роҳи ҳодиса. Коркардкунандаҳои оддӣ дар марҳилаи болоравӣ кор мекунанд: button → li → ul
Муқоиса аз ҳаёт
Ҳубобчаи ҳаво дар стакани чой аз таги он ба рӯи об боло меравад ва аз ҳамаи қабатҳо мегузарад. Клик ба тугма низ ҳамин тавр «боло меравад»: аввал ба тугма хабар медиҳад, баъд ба корточка, баъд ба рӯйхат, баъд ба body, document. Ва боз ин ба идораи Душанбе монанд аст: корманд хабарро ба сардори шӯъба мерасонад, ӯ — ба директор, ӯ — ба соҳиб.
Фурӯравӣ (capturing). Ҳодиса аз document ба ҳадаф мефурояд. Коркардкунандаҳо дар ин ҷо танҳо дар сурате кор мекунанд, ки шумо махсус хоҳиш карда бошед: { capture: true }. Кам лозим мешавад.
Ҳадаф (target). Ҳодиса ба элементе мерасад, ки ба он клик карданд.
Болоравӣ (bubbling). Ҳодиса боз ба боло то худи document мебарояд. Дар ин марҳила ҳамаи коркардкунандаҳои оддӣ кор мекунанд.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<ul id="list">
<li id="card"><button id="btn">В корзину</button></li>
</ul>` ;
for (const id of ["btn" , "card" , "list" ]) {
document.getElementById (id).addEventListener ("click" , (e) => {
console.log (`сработал ${e.currentTarget.id}, а кликнули по ${e.target.id}` );
});
}
document.getElementById ("btn" ).click ();
Ба ду чиз диққат диҳед: тартиб аз поён ба боло меравад, ва target дар тамоми роҳ яке ва ҳамон мемонад — ҳамон, ки ба вай клик карданд. Танҳо currentTarget тағйир меёбад.
Зинда бинед
▶ Запустить -ро пахш кунед ва ба тугмаи дарунӣ, баъд ба чаҳорчӯбаи миёна ва берунӣ клик кунед. Байрақчаро фаъол кунед — ва болоравӣ дар тугма меистад.
Роҳи ҳодиса · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< div id ="outer" class ="box" > outer
< div id ="middle" class ="box" > middle
< button id ="inner" > inner (нажмите)</ button >
</ div >
</ div >
< label > < input type ="checkbox" id ="stop" > stopPropagation на кнопке</ label >
< button id ="clear" > Очистить журнал</ button >
< ol id ="log" > </ ol >
.box { padding : 10px 14px ; margin : 6px 0 ; border : 2px solid #98a2b3 ; border-radius : 10px ; }
#outer { border-color : #2e90fa ; }
#middle { border-color : #f79009 ; }
button { font : inherit; padding : 4px 10px ; }
const log = document.querySelector ("#log" );
const stop = document.querySelector ("#stop" );
function write (text) {
const li = document.createElement ("li" );
li.textContent = text;
log.append (li);
console.log (text);
}
for (const id of ["outer" , "middle" , "inner" ]) {
document.getElementById (id).addEventListener ("click" , (event) => {
write (`${event.currentTarget.id} (target: ${event.target.id})` );
if (id === "inner" && stop.checked) event.stopPropagation ();
});
}
document.querySelector ("#clear" ).addEventListener ("click" , (e) => {
log.innerHTML = "" ;
e.stopPropagation ();
});
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
stopPropagation: роҳро қатъ кардан
event.stopPropagation() болоравиро қатъ мекунад: падарон ҳодисаро намегиранд. Ҷолиб менамояд, аммо эҳтиёткорона истифода баред. Ҳодисаи қатъшуда ба коди бегона низ намерасад — масалан, ба ҳисобкунаки аналитика дар document, ва шумо муддати дароз мекобед, ки чаро он кликҳоро «гузашта мегузорад». Одатан беҳтар аст дар коркардкунандаи падар санҷид , ки маҳз ба куҷо клик карданд: event.target === event.currentTarget.
Фурӯравӣ: { capture: true }
Агар ҳамчун аргументи сеюм true ё { capture: true } диҳед, коркардкунанда дар марҳилаи фурӯравӣ кор мекунад — пештар аз худи ҳадаф. Ҳамин тавр ҳодисаро то расидан ба поён «пешвоз гирифтан» мумкин аст.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<div id="wrap"><button id="btn">Кнопка</button></div>` ;
const wrap = document.querySelector ("#wrap" );
const btn = document.querySelector ("#btn" );
wrap.addEventListener ("click" , () => console.log ("wrap: всплытие" ));
wrap.addEventListener ("click" , () => console.log ("wrap: перехват" ), { capture: true });
btn.addEventListener ("click" , () => console.log ("button: цель" ));
btn.click ();
Тартиб: аввал фурӯравӣ дар wrap (поён рафтан), баъд худи тугма, баъд болоравӣ дар wrap.
На ҳама чиз боло меравад
Ҳодисаҳои focus ва blur боло намераванд (ба ҷои онҳо дар падар focusin / focusout-ро бишнавед), mouseenter ва mouseleave низ — не (mouseover / mouseout-ро гиред). Ғайр аз ин, ҳодисаҳои дастӣ сохташуда ба таври пешфарз боло намераванд: бояд ошкоро new Event("input", { bubbles: true }) навишт.
Хатои маъмул: ҳодисаи дастӣ боло намеравад · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<div id="form"><input id="field"></div>` ;
const form = document.querySelector ("#form" );
const field = document.querySelector ("#field" );
form.addEventListener ("input" , () => console.log ("форма услышала ввод" ));
field.dispatchEvent (new Event ("input" )); // ✖ боло намеравад — хомӯшӣ
console.log ("---" );
field.dispatchEvent (new Event ("input" , { bubbles: true })); // ✔ боло меравад
Барои муфассалтар хондан: learn.javascript.ru — Всплытие и погружение · MDN — Event.stopPropagation
Амалиёт: мустаҳкам мекунем
ВАЗИФАИ 5.1 Роҳи кликро пешгӯӣ кун осон
Се элементи дарунмонда, дар ҳар кадом коркардкунандаи худӣ. Дар prediction идентификаторҳоро бо тартибе нависед, ки коркардкунандаҳо баъди клик ба тугмаи аз ҳама дарунии #c кор мекунанд. Консол танҳо «верно» ё «неверно» мегӯяд.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<div id="a">
<div id="b">
<button id="c">Кнопка</button>
</div>
</div>` ;
const actual = [];
for (const id of ["a" , "b" , "c" ]) {
document.getElementById (id).addEventListener ("click" , () => actual.push (id));
}
document.getElementById ("c" ).click ();
const prediction = []; // масалан ["x", "y", "z"]
console.log (prediction.join (" " ) === actual.join (" " ) ? "Прогноз верный" : "Прогноз неверный" );
Натиҷаи интизоршаванда Прогноз верный
Ишора 1 Схемаро ба ёд оред: ҳодиса аз ҳадаф оғоз мешавад ва боло мебарояд. Ҳадаф дар ин ҷо кист?
Ишора 2 Тартиб аз элементи аз ҳама чуқур ба элементи аз ҳама берунӣ меравад. Метавон бо илова кардани муваққатии console.log(actual.join(" ")) нигоҳ кард.
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 5.2 Пештар гирифтан миёна
Тугмаи #btn ва печонаки он #wrap аллакай коркардкунандаҳои оддӣ доранд. Яктои дигарро илова кунед — дар печонак, аммо дар марҳилаи фурӯравӣ : он бояд «Перехват: wrap»-ро пеш аз ҳама чоп кунад. Тартиби интизоршаванда дар зер оварда шудааст.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<div id="wrap"><button id="btn">Купить</button></div>` ;
const wrap = document.querySelector ("#wrap" );
const btn = document.querySelector ("#btn" );
btn.addEventListener ("click" , () => console.log ("Кнопка" ));
wrap.addEventListener ("click" , () => console.log ("Всплытие: wrap" ));
// коди шумо инҷо
btn.click ();
Натиҷаи интизоршаванда Перехват: wrap
Кнопка
Всплытие: wrap
Ишора 1 Марҳилаи фурӯравӣ бо аргументи сеюми addEventListener фаъол мешавад.
Ишора 2 wrap.addEventListener("click", () => console.log("Перехват: wrap"), { capture: true });
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 5.3 Тирезаи модалӣ худ аз худ баста мешавад миёна
Заминаи хокистарранги #overlay тирезаро бо клик мебандад. Дар дохил худи тирезаи #modal ҷойгир аст. Хато: клик дар дохили тиреза низ онро мебандад, зеро ҳодиса то замина боло меравад. Чунон ислоҳ кунед, ки клик ба тиреза танҳо «Клик внутри окна» чоп кунад, ва клик ба замина — «Окно закрыто».
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<div id="overlay">
<div id="modal">Вы уверены?</div>
</div>` ;
const overlay = document.querySelector ("#overlay" );
const modal = document.querySelector ("#modal" );
modal.addEventListener ("click" , () => {
console.log ("Клик внутри окна" );
});
overlay.addEventListener ("click" , () => {
console.log ("Окно закрыто" );
});
modal.click ();
overlay.click ();
Натиҷаи интизоршаванда Клик внутри окна
Окно закрыто
Ишора 1 Онро чун ҳаст иҷро кунед: «Окно закрыто» ду маротиба чоп мешавад. Бори аввал — баъди клик ба тиреза, аз сабаби болоравӣ.
Ишора 2 Ду роҳ. Тез: дар коркардкунандаи modal параметри event-ро илова кунед ва event.stopPropagation()-ро иҷро кунед. Эҳтиёткортар: дар коркардкунандаи overlay танҳо ҳангоме бандед, ки event.target === event.currentTarget.
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 5.4 Роҳнишони клик душвор
Барои ислоҳи аналитика бояд донист, ки маҳз дар куҷо клик карданд. Ба #shop як коркардкунанда овезед, ки аз event.target тавассути parentElement то #shop (аз ҷумла) боло мебарояд ва роҳро дар формати «тег#id.класс < … < main#shop» чоп мекунад. Агар элемент id ё класс надошта бошад — онҳо навишта намешаванд. Функсияи describe(el) аллакай ҳамчун ҷой барои шумо тайёр шудааст.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<main id="shop">
<article class="card">
<h3 id="title">Дыня</h3>
<p class="info">Цена: <b id="price">12</b></p>
<button id="buy">Купить</button>
</article>
</main>` ;
const shop = document.querySelector ("#shop" );
// тег бо ҳарфи хурд + "#id", агар бошад + ".класс", агар бошад
function describe (el) {
// коди шумо инҷо
}
// коди шумо инҷо: коркардкунандаи клик дар shop
for (const id of ["price" , "title" , "buy" , "shop" ]) {
document.getElementById (id).click ();
}
Натиҷаи интизоршаванда b#price < p.info < article.card < main#shop
h3#title < article.card < main#shop
button#buy < article.card < main#shop
main#shop
Ишора 1 describe: el.tagName.toLowerCase() + (el.id ? "#" + el.id : "") + (el.className ? "." + el.className : ""). Функсияро алоҳида санҷед, ва барои якчанд элемент даъват кунед.
Ишора 2 Давраи боло рафтан: let el = event.target; const path = []; while (true) { path.push(describe(el)); if (el === shop) break; el = el.parentElement; }, баъд path.join(" < ").
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
06 Вакилкунии ҳодисаҳо
Фарз кунем, шумо рӯйхати 50 кор доред ва ҳар кадом тугмаи «Удалить» дорад. Фикри аввал: бо давра гузашта, ба ҳар тугма коркардкунанда овехтан. Ин кор мекунад, аммо се мушкилот ҳаст:
Коркардкунандаҳои зиёд. 50 тугма — 50 шунаванда дар хотира. Агар сатрҳо 5000 бошанд-чӣ?
Элементҳои нав «кар» мешаванд. Корбар кор илова кард — тугмаи нав коркардкунанда надорад, зеро давра пештар кор карда буд.
Кори изофӣ. Ҳар як элементро бояд обуна кард ва ҳангоми нест кардан — обунаро бекор кард.
Ҳал аз болоравии бахши гузашта истифода мебарад. Клик ба ҳар тугма ба ҳар ҳол боло мебарояд то падари умумӣ — рӯйхат. Пас, як коркардкунанда дар падар кифоя аст: он мефаҳмад, ки маҳз кӣ ҳадаф буд, ва қарор медиҳад, ки чӣ кор кунад. Ин вакилкунӣ номида мешавад — падар ҳодисаҳоро «бо вакилнома» аз номи ҳамаи фарзандон қабул мекунад.
Муқоиса аз ҳаёт
Дар MakeFirstStep дар назди дари ҳар аудитория посбон нест — як маъмур дар қабулгоҳ ҳаст. Ҳамаи саволҳо ба ӯ меравад: «Аудитория 3 дар куҷост?», «Имрӯз кӣ дарс медиҳад?». Вақте аудиторияи нав мекушоянд, посбони нав киро кардан лозим нест — маъмур аллакай огоҳ аст. Бо вакилкунӣ низ ҳамин тавр: як «маъмур» (падар) ҳамаро хизмат мерасонад, аз ҷумла онҳое, ки баъдтар пайдо мешаванд.
Ду равиш паҳлӯ ба паҳлӯ
Коркардкунанда дар ҳар элемент
JavaScript
for (const btn of list.querySelectorAll ("button" )) {
btn.addEventListener ("click" , remove);
}
// тугмаҳои нав — бе коркардкунанда
Як коркардкунанда дар падар
JavaScript
list.addEventListener ("click" , (event) => {
const btn = event.target.closest ("button" );
if (!btn) return ;
remove (btn);
});
// барои тугмаҳои оянда низ кор мекунад
Абзори нав: closest
Мушкилот: event.target — элементи аз ҳама чуқур аст, ки ба он клик карданд. Агар дар тугма нишонаи <span> бошад, ҳадаф нишона мешавад, на тугма. Бояд аз ҳадаф ба элементи лозимӣ «боло рафт». Барои ин усули element.closest(selector) ҳаст: он худи элементро месанҷад, баъд падарро, баъд падари падарро — ва аввалин мувофиқро аз рӯи селектори CSS бармегардонад. Агар чунин набошад — null.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<ul id="list">
<li class="item"><button class="del"><span class="icon">✕</span></button></li>
</ul>` ;
const icon = document.querySelector (".icon" );
console.log (icon.closest ("button" ).className); // del — ба 1 сатҳ боло рафтем
console.log (icon.closest ("li" ).className); // item — ба 2 сатҳ
console.log (icon.closest (".icon" ) === icon); // true — аввал худи элемент санҷида мешавад
console.log (icon.closest ("table" )); // null — чунин аҷдод нест
Боз як абзор: атрибутҳои data
Чӣ тавр фаҳмидан мумкин аст, ки маҳз кадом тугмаро заданд — «нест кардан» ё «ба интихобшуда»? Ва дар кадом сатр? Аз рӯи матни тугма ҳадс заданӣ нестем-ку. Барои чунин нишонаҳо дар HTML атрибутҳои data-* ҳастанд: шумо худатон ном меандешед, ва дар JS тавассути element.dataset мехонед.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<li data-id="42" data-user-name="Мадина"><button data-action="remove">✕</button></li>` ;
const li = document.querySelector ("li" );
const btn = document.querySelector ("button" );
console.log (li.dataset.id); // "42" — ҳамеша сатр!
console.log (li.dataset.userName); // data-user-name → userName (camelCase)
console.log (btn.dataset.action); // "remove"
console.log (Number (li.dataset.id) + 1 ); // 43 — адад худамон месозем
Қолаби вакилкунӣ
Як коркардкунанда дар падари умумӣ — рӯйхат, ҷадвал, меню.
Элементи лозимиро ёбед: const btn = event.target.closest("button[data-action]");
Чизе наёфтем — мебароем: if (!btn) return; (клик ба ҷое, ки тугма нест).
Санҷед, ки тугма дар дохили рӯйхати шумост: if (!list.contains(btn)) return; Вақте лозим аст, ки рӯйхатҳо дар якдигар ҷойгиранд.
Ба сатр боло равед: const li = btn.closest("li");
Аз рӯи dataset қарор диҳед: if (btn.dataset.action === "remove") li.remove();
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<ul id="list">
<li data-id="1">Нон <button data-action="remove"><span>✕</span></button></li>
<li data-id="2">Чой <button data-action="remove"><span>✕</span></button></li>
</ul>` ;
const list = document.querySelector ("#list" );
list.addEventListener ("click" , (event) => {
const btn = event.target.closest ("button[data-action]" );
if (!btn || !list.contains (btn)) return ;
const li = btn.closest ("li" );
if (btn.dataset.action === "remove" ) {
console.log ("Удаляю №" + li.dataset.id);
li.remove ();
}
});
list.querySelector ("span" ).click (); // ба нишона дар дохили тугма клик карданд — кор мекунад!
console.log ("Осталось:" , list.children.length);
// баъдтар банди нав илова мекунем — коркардкунанда лозим нест
const newLi = document.createElement ("li" );
newLi.dataset.id = 3 ;
newLi.innerHTML = `Лагман <button data-action="remove"><span>✕</span></button>` ;
list.append (newLi);
newLi.querySelector ("button" ).click ();
console.log ("Осталось:" , list.children.length);
Худатон кӯшиш кунед
▶ Запустить -ро пахш кунед. Якчанд бандро нест кунед, баъд бо тугмаи «Добавить пункт» банди нав илова кунед — ва боварӣ ҳосил кунед, ки тугмаи «✕»-и банди нав бе як сатри изофии обуна кор мекунад.
Менюи чойхона · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< button id ="add" > Добавить пункт</ button >
< ul id ="menu" >
< li > < span class ="name" > Оши палав</ span > < button data-action ="remove" > ✕</ button > </ li >
< li > < span class ="name" > Лагман</ span > < button data-action ="remove" > ✕</ button > </ li >
</ ul >
li { padding : 4px 0 ; }
button { font : inherit; padding : 2px 10px ; border-radius : 8px ; border : 1px solid #d0d5dd ; background : #fff ; cursor : pointer; }
const menu = document.querySelector ("#menu" );
const dishes = ["Манту" , "Самбуса" , "Шурпо" , "Кабоб" ];
let next = 0 ;
// ЯК коркардкунанда барои тамоми рӯйхат
menu.addEventListener ("click" , (event) => {
const btn = event.target.closest ("button[data-action]" );
if (!btn) return ;
const li = btn.closest ("li" );
console.log ("Убрали:" , li.querySelector (".name" ).textContent);
li.remove ();
});
document.querySelector ("#add" ).addEventListener ("click" , () => {
const li = document.createElement ("li" );
li.innerHTML = `<span class="name"></span> <button data-action="remove">✕</button>` ;
li.querySelector (".name" ).textContent = dishes[next++ % dishes.length];
menu.append (li);
});
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Хатоҳои маъмули вакилкунӣ
1. Ба ҷои closest event.target-ро истифода мебаранд. Клик ба нишона дар дохили тугма ҳадафи нишона медиҳад — ва санҷиши target.tagName === "BUTTON" кор намекунад.
2. Ҳодисаеро вакил мекунанд, ки боло намеравад. focus, blur, mouseenter то падар намерасанд — focusin, focusout, mouseover-ро гиред.
3. if (!btn) return-ро фаромӯш мекунанд. Клик ба ҷои холии рӯйхат низ коркардкунандаро даъват мекунад, ва btn null мешавад.
Хатои маъмул: клик ба нишона дар дохили тугма мушоҳида нашуд · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<ul id="list">
<li>Нон <button><span id="icon">✕</span></button></li>
</ul>` ;
const list = document.querySelector ("#list" );
list.addEventListener ("click" , (event) => {
if (event.target.tagName === "BUTTON" ) { // ✖ ҳадаф — ин SPAN аст
console.log ("Кнопка нажата" );
} else {
console.log ("Цель:" , event.target.tagName); // мо дар ин ҷо мерасем
}
});
document.querySelector ("#icon" ).click ();
Баръакс ҳам мешавад: вакилкунӣ на ҳамеша ҳалли беҳтарин аст. Агар элемент як бошад (масалан, тугмаи «Войти»), танҳо коркардкунандаро ба он овезед. Вакилкунӣ барои рӯйхатҳо, ҷадвалҳо, менюҳо лозим аст — дар он ҷое, ки элементҳо бисёранд ё илова ва нест карда мешаванд.
Барои муфассалтар хондан: learn.javascript.ru — Делегирование событий · MDN — Element.closest · MDN — data-атрибуты
Амалиёт: мустаҳкам мекунем
ВАЗИФАИ 6.1 Як шунаванда барои тамоми меню осон
Менюи ошхона — рӯйхати #menu бо се таом. Як коркардкунандаи клик ба худи рӯйхат овезед. Он «Выбрано: название»-ро танҳо дар сурате чоп мекунад, ки ҳадаф банди <li> бошад. Клик ба худи рӯйхат (берун аз бандҳо) бояд нодида гирифта шавад.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<ul id="menu"><li>Оши палав</li><li>Лагман</li><li>Манту</li></ul>` ;
const menu = document.querySelector ("#menu" );
// коди шумо инҷо: як коркардкунанда дар menu
for (const li of menu.children) {
li.click ();
}
menu.click (); // берун аз бандҳо — вокуниш набояд бошад
Натиҷаи интизоршаванда Выбрано: Оши палав
Выбрано: Лагман
Выбрано: Манту
Ишора 1 Элементе, ки ба он клик карданд, — event.target. Тегашро санҷед: event.target.tagName === "LI". Барои клик ба худи рӯйхат target UL мешавад.
Ишора 2 menu.addEventListener("click", (event) => { if (event.target.tagName !== "LI") return; console.log("Выбрано: " + event.target.textContent); });
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 6.2 Тугмаҳои «писанд» ва «нест кардан» миёна
Дар рӯйхат се таом ҳаст, ҳар кадом тугмаҳои data-action="like" ва data-action="remove" дорад. Як коркардкунанда барои #list тавассути closest ва dataset нависед. Барои «like» «Нравится: название (№id)», барои «remove» — «Удалено: название (№id)» чоп кунед ва бандро нест кунед . Кликро берун аз тугма нодида гиред. Ном дар .name, id — дар data-id-и <li> аст.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<ul id="list">
<li data-id="1"><span class="name">Оши палав</span> <button data-action="like">♥</button> <button data-action="remove">✕</button></li>
<li data-id="2"><span class="name">Лагман</span> <button data-action="like">♥</button> <button data-action="remove">✕</button></li>
<li data-id="3"><span class="name">Манту</span> <button data-action="like">♥</button> <button data-action="remove">✕</button></li>
</ul>` ;
const list = document.querySelector ("#list" );
// коди шумо инҷо
const press = (id, action) =>
document.querySelector (`li[data-id="${id}"] [data-action="${action}"]` ).click ();
press (2 , "like" );
press (3 , "remove" );
press (1 , "like" );
list.querySelector (".name" ).click (); // клик ба ном — нодида мегирем
console.log ("Осталось: " + list.children.length);
Натиҷаи интизоршаванда Нравится: Лагман (№2)
Удалено: Манту (№3)
Нравится: Оши палав (№1)
Осталось: 2
Ишора 1 Оғози коркардкунанда: const btn = event.target.closest("button[data-action]"); if (!btn) return; const li = btn.closest("li");
Ишора 2 Ном: li.querySelector(".name").textContent, id: li.dataset.id, амал: btn.dataset.action. Шохаҳои if … else if аз рӯи амал; барои нест кардан — li.remove() баъди чопи сатр.
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 6.3 Банди нав ҷавоб намедиҳад миёна
Дар меню ба ҳар банд коркардкунандаи худӣ овехта шудааст. Барнома баъдтар банди «Самбуса»-ро илова кард — ва он коркардкунанда надорад, дар ҳоле ки дар консол се сатр интизор аст. Обунаро аз нав нависед: ба ҷои давра як коркардкунанда барои #menu. Кодро дар зери сатри «приложение добавляет пункт» тағйир надиҳед.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `<ul id="menu"><li>Нон</li><li>Чой</li></ul>` ;
const menu = document.querySelector ("#menu" );
// Ҳоло: барои ҳар банд коркардкунанда. Онро бо ЯК коркардкунанда дар menu иваз кунед
for (const li of menu.querySelectorAll ("li" )) {
li.addEventListener ("click" , () => console.log ("Заказано: " + li.textContent));
}
// --- барнома банд илова мекунад (тағйир надиҳед) ---
const extra = document.createElement ("li" );
extra.textContent = "Самбуса" ;
menu.append (extra);
for (const li of menu.children) {
li.click ();
}
Натиҷаи интизоршаванда Заказано: Нон
Заказано: Чой
Заказано: Самбуса
Ишора 1 Давраи for-ро бо обунаҳо нест кунед. Ба ҷои он — як сатри menu.addEventListener("click", …).
Ишора 2 Дар коркардкунанда: const li = event.target.closest("li"); if (!li) return; console.log("Заказано: " + li.textContent);
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 6.4 Сабад бо «+» ва «−» душвор
Сабади мағоза. Ҳар сатри <li> нарх дар data-price, миқдор дар .qty ва се тугма дорад: inc (+1), dec (−1; агар 0 шуд — сатр нест карда мешавад) ва del (сатрро фавран нест кардан). Як коркардкунанда барои #cart. Баъди ҳар амал чоп: «Итого: N сомони», ва агар сабад холӣ бошад — «Корзина пуста». Функсияи press аллакай тайёр аст.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<ul id="cart">
<li data-price="4"><span class="name">Нон</span>
<button data-action="dec">−</button> <b class="qty">1</b> <button data-action="inc">+</button>
<button data-action="del">✕</button></li>
<li data-price="18"><span class="name">Чой</span>
<button data-action="dec">−</button> <b class="qty">2</b> <button data-action="inc">+</button>
<button data-action="del">✕</button></li>
</ul>` ;
const cart = document.querySelector ("#cart" );
function printTotal () {
// коди шумо инҷо: ҷамъ аз рӯи ҳамаи сатрҳо ё «Корзина пуста»
}
// коди шумо инҷо: як коркардкунанда дар cart
const press = (name, action) => {
const li = [... cart.children].find ((x) => x.querySelector (".name" ).textContent === name);
li.querySelector (`[data-action="${action}"]` ).click ();
};
press ("Нон" , "inc" );
press ("Чой" , "dec" );
press ("Чой" , "dec" );
press ("Нон" , "del" );
Натиҷаи интизоршаванда Итого: 44 сомони
Итого: 26 сомони
Итого: 8 сомони
Корзина пуста
Ишора 1 Корро тақсим кунед: printTotal() танҳо аз болои cart.children мегузарад ва Number(li.dataset.price) * Number(li.querySelector(".qty").textContent)-ро ҷамъ мекунад — он дар бораи тугмаҳо чизе намедонад.
Ишора 2 Дар коркардкунанда: closest("button[data-action]"), баъд li = btn.closest("li"), qty — элементи li.querySelector(".qty"). Барои dec: qty.textContent = Number(qty.textContent) - 1; if (Number(qty.textContent) === 0) li.remove();. Дар охири ҳар клик — printTotal().
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
07 Блоки ЗС: хаторо чӣ тавр тавсиф кардан
«Тугма кор намекунад» — ибораи аз ҳама маъмули барномасозони навомӯз. Ва аз ҳама бефоида: на одам, на ЗС намефаҳмад, ки чӣ маҳз вайрон шуд. Ҳодисаҳо машқи олӣ мебошанд, чунки хатоҳо дар онҳо ҳамеша як навъ аст: «интизор будам, ки ҳангоми клик X мешавад, аммо Y рух медиҳад (ё ҳеҷ чиз)». Тавсифи чунин хаторо ёд гиред — ва аз ЗС ҷавоби дақиқ мегиред, ва аксар вақт худатон сабабро меёбед, ҳангоми навиштани тавсиф.
Қоидаҳои курс дар бораи ЗС — ёдрас мекунем
1) Аввал 15 дақиқа худатон кӯшиш мекунед. 2) Коде, ки сатр ба сатр шарҳ дода наметавонед, ворид намекунед — ҳангоми санҷиши вазифаи хонагӣ омӯзгор ҳақ дорад дар бораи ҳар сатр бипурсад. 3) Дар промпт ҳамеша: контекст → вазифа → маҳдудиятҳо → формати ҷавоб → санҷиш.
Гузориши заиф ва қавии хато
тугмаи нест кардан дар рӯйхат кор намекунад, чароНусха бардоштан
Контекст: JavaScript меомӯзам, рӯйхати харидро бо JS-и холис (DOM, ҳодисаҳо) менависам.
Хато: интизорам, ки клик ба тугмаи «✕» сатрро аз рӯйхат нест мекунад. Мегирам: танҳо сатри аввал нест мешавад, бандҳои нав умуман нест намешаванд. Дар консол хато нест.
Коди ҳадди аққал (HTML + JS, 12 сатр):
[код]
Чӣ аллакай кӯшиш кардам: console.log(event.target)-ро чоп кардам — ҳангоми клик ба нишона дар дохили тугма он ҷо SPAN аст.
Формати ҷавоб: 3 фарзияи сабаб аз рӯи эҳтимол, ба ҳар кадом — чӣ тавр санҷидан. Кодро пурра аз нав нанавис.
Санҷиш: баъди ҷавоб ман худам ҳар фарзияро дар консол месанҷам.Нусха бардоштан
Чӣ тавр намунаи ҳадди аққал сохтан
Қисми мушкилдорро нусха кунед ба файли алоҳида ё ба қуттии санҷиш дар ин саҳифа.
Ҳама чизи изофиро партоед: услубҳо, компонентҳои ҳамсоя, функсияҳое, ки ба хато дахл надоранд. Баъди ҳар нест кардан санҷед — хато ҳанӯз такрор мешавад?
Маълумоти воқеиро иваз кунед бо 2–3 элементи оддӣ.
Се чизро сабт кунед: шумо чӣ мекунед (клик мекунам ба …), чӣ интизор будед, чӣ гирифтед. Хаторо аз консол айнан нусха кунед, бо суханони худ нақл накунед.
Боз як бор хонед. Аксар вақт хато маҳз дар қадами 2 ёфт мешавад. Ин усули маъруфи «мурғобии резинӣ» аст: вақте мушкилотро бо овоз шарҳ медиҳед, худатон хаторо мебинед.
Қолаби гузориши хато
Контекст: [лоиҳа чӣ аст, мавзӯъ кадом аст, чӣ аллакай медонам].
Интизор будам: [чӣ бояд рӯй диҳад].
Гирифтам: [воқеан чӣ рӯй медиҳад + матни дақиқи хато аз консол].
Коди ҳадди аққал: [на зиёда аз 20 сатр].
Чӣ кӯшиш кардам: [1–2 қадами ислоҳ ва чӣ нишон доданд].
Формати ҷавоб: 3 фарзия аз рӯи эҳтимол, чӣ тавр санҷидани ҳар кадом. Кодро пурра аз нав нанавис.
Санҷиш: фарзияҳоро навбат месанҷам ва менависам, кадомаш тасдиқ шуд.Нусха бардоштан
Вакилкуниро дар коди худ шарҳ додан
Ин сатр аз китобхонаи промптҳои курс аст. Коди рӯйхати худро гузоред ва шарҳ пурсед — аммо санҷед, ки мефаҳмед, чаро event.target кор мекунад:
Вакилкунии ҳодисаҳоро дар ин мисол шарҳ деҳ: [код]. Нусхаи ҳадди аққалро тавассути як коркардкунанда дар падар нишон деҳ. Бо суханони оддӣ шарҳ деҳ, ки event.target чист ва чаро дар ин ҷо closest лозим аст. Ҷавоб — қадам ба қадам, аз 15 сатр дарозтар не.Нусха бардоштан
Санҷиши ҷавоб: ҷавоби ЗС-ро пӯшед ва бо суханони худ ба ҳамсояи миз шарҳ диҳед, ки клик ба тугма чӣ тавр ба рӯйхат мерасад. Намебарояд — бахшҳои 05–06-ро боз хонед.
Хатоҳои маъмули ЗС дар ҳодисаҳо
Дар ҷавоби ЗС чиро мебинед Мушкилот дар чист Чӣ тавр ислоҳ кардан onclick="..." бевосита дар HTMLАломатгузорӣ ва кодро омехта мекунад, нигоҳубин душвор аст addEventListener дар файли JSДавра бо обуна ба ҳар li / тугма Элементҳои нав бе коркардкунанда мемонанд Вакилкунӣ дар падар if (e.target.tagName === "BUTTON")Ба нишона дар дохили тугма кор нахоҳад кард e.target.closest("button")list.innerHTML += "<li>…</li>" дар коркардкунандаТамоми рӯйхатро аз нав месозад: ҳолатҳо ва обунаҳо дар элементҳо гум мешаванд createElement + appendШакл: click дар тугмаи «Отправить» Enter дар майдон шаклро бе клик мефиристад submit дар шакл + preventDefault()e.stopPropagation() «барои эҳтиёт»Коркардкунандаҳои бегонаро дар боло вайрон мекунад (аналитика, бастани меню) Санҷиши e.target === e.currentTarget btn.addEventListener("click", handler())Функсия фавран даъват мешавад, на бо клик Бе қавс: handler
Амалиёт бо ЗС
ВАЗИФАИ 7.1 Хато: клик ба нишона миёна
Рӯйхати интихобшуда бояд ҳангоми клик ба ситорача «В избранное: название» чоп кунад. Ситорача — ин <span class="icon"> дар дохили тугма. Ҳоло чизе чоп намешавад. Аввал худатон сабабро ёбед (15 дақиқа!). Баъд — дар шарҳи болои код — барои ЗС гузориши хатоеро аз рӯи қолаб (интизор будам / гирифтам / коди ҳадди аққал) тартиб диҳед ва бо фарзияи ЗС муқоиса кунед. Ба чопи интизоршаванда бирасед.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
document.body.innerHTML = `
<ul id="menu">
<li><span class="name">Дыня</span> <button class="fav"><span class="icon">★</span></button></li>
<li><span class="name">Гранат</span> <button class="fav"><span class="icon">★</span></button></li>
</ul>` ;
const menu = document.querySelector ("#menu" );
menu.addEventListener ("click" , (event) => {
if (event.target.tagName === "BUTTON" ) {
const name = event.target.parentElement.querySelector (".name" ).textContent;
console.log ("В избранное: " + name);
}
});
// корбар ба нишонаи ★ дар дохили тугма клик мекунад
for (const icon of document.querySelectorAll (".icon" )) {
icon.click ();
}
Натиҷаи интизоршаванда В избранное: Дыня
В избранное: Гранат
Ишора 1 Ба коркардкунанда console.log(event.target.tagName)-ро илова кунед. Ҳангоми клик ба нишона чӣ мебинед? Оё он ба "BUTTON" баробар аст?
Ишора 2 Санҷишро бо const btn = event.target.closest(".fav"); if (!btn) return; иваз кунед, ва номро аз тугма ҷустуҷӯ кунед: btn.closest("li").querySelector(".name").textContent.
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
ВАЗИФАИ 7.2 Гузориши хаторо ҷамъ кунед осон
Вазъият: скрипт дар <head> пайваст шудааст, аммо тугма дар <body> истодааст. Дар консол хатои TypeError: Cannot read properties of null (reading 'addEventListener'). Гузориши хаторо барои ЗС дар тағйирёбандаи report нависед (ин матн аст, ба ҳеҷ ҷо фиристода намешавад). Блокҳои «Ожидал:», «Получил:», «Что пробовал:», матни дақиқи хато ва коди ҳадди аққал бо addEventListener лозиманд. Дарозӣ — на зиёда аз 600 аломат. Код худаш матни шуморо месанҷад. Дар дохили матн аз нохунакҳои баръакс истифода набаред.
Таҳрир кардан мумкин аст · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
const report = `
` ; // гузориши хаторо байни нохунакҳо нависед
const checks = [
["Есть «Ожидал:»" , report.includes ("Ожидал:" )],
["Есть «Получил:»" , report.includes ("Получил:" )],
["Есть точный текст ошибки" , report.includes ("Cannot read properties of null" )],
["Есть минимальный код" , report.includes ("addEventListener" )],
["Есть «Что пробовал:»" , report.includes ("Что пробовал:" )],
["Не длиннее 600 символов" , report.length <= 600 ]
];
for (const [name, ok] of checks) {
console.log ((ok ? "✔ " : "✖ " ) + name);
}
Натиҷаи интизоршаванда ✔ Есть «Ожидал:»
✔ Есть «Получил:»
✔ Есть точный текст ошибки
✔ Есть минимальный код
✔ Есть «Что пробовал:»
✔ Не длиннее 600 символов
Ишора 1 Скелет: «Ожидал: … Получил: … Минимальный код: … Что пробовал: …». Ҳар блок — дар сатри нав бевосита дар дохили report.
Ишора 2 Хаторо бо суханони худ нақл накунед — онро айнан гузоред. Дар коди ҳадди аққал ду сатр кофист: const btn = document.querySelector("#buy"); ва btn.addEventListener("click", () => console.log("Куплено"));. Фикр кунед, ки агар скрипт пештар аз хондани <body> аз ҷониби браузер иҷро шавад, чӣ мешавад.
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
08 Амалиёт дар дарс: рӯйхат бо тугмаҳо
«Харид барои бозор»-ро месозем — рӯйхате, ки дар ҳар банд ду тугма дорад: ♥ ба интихобшуда ва ✕ нест кардан . Коркардкунанда як аст, барои тамоми рӯйхат. Бо се қадам мегузарем, баъди ҳар кадом ▶ Запустить -ро пахш кунед ва бо даст санҷед. Нусха накунед — худатон чоп кунед, ин чанд маротиба беҳтар ба ёд мемонад.
Хабаркашӣ. Як коркардкунанда дар рӯйхат. Мефаҳмем, ки ба кадом тугма ва дар кадом сатр клик карданд.
Амалҳо. ♥ синфи fav-и сатрро иваз мекунад, ✕ сатрро нест мекунад.
Ҳисобкунак. Баъди ҳар амал «Всего: N, избранных: M»-ро нав мекунем. Бандҳои нав фавран кор мекунанд.
Қадами 1. Хабаркашӣ
То ҳол чизеро тағйир намедиҳем — танҳо ба консол чоп мекунем, ки аз клик чӣ фаҳмидем. Ба ♥, ба ✕, ба ном ва берун аз тугмаҳо клик кунед.
Қадами 1 · Хабаркашӣ · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< h4 > Покупки на базар</ h4 >
< ul id ="list" >
< li > < span class ="name" > Морковь</ span > < button data-action ="fav" title ="В избранное" > ♥</ button > < button data-action ="remove" title ="Удалить" > ✕</ button > </ li >
< li > < span class ="name" > Рис</ span > < button data-action ="fav" title ="В избранное" > ♥</ button > < button data-action ="remove" title ="Удалить" > ✕</ button > </ li >
< li > < span class ="name" > Лук</ span > < button data-action ="fav" title ="В избранное" > ♥</ button > < button data-action ="remove" title ="Удалить" > ✕</ button > </ li >
</ ul >
< p id ="count" > </ p >
h4 { margin : 0 0 8px ; }
ul { list-style : none; padding : 0 ; margin : 0 ; max-width : 340px ; }
li { display : flex; gap : 8px ; align-items : center; padding : 8px 10px ; border : 1px solid #e4e7ec ; border-radius : 10px ; margin-bottom : 6px ; }
.name { flex : 1 ; }
button { font : inherit; border : 1px solid #d0d5dd ; background : #fff ; border-radius : 8px ; cursor : pointer; padding : 2px 8px ; }
li.fav { background : #fef3f2 ; border-color : #fda29b ; }
li.fav .name { font-weight : 700 ; color : #b42318 ; }
li.fav [data-action="fav" ] { color : #d92d20 ; }
#count { color : #667085 ; font-size : 14px ; }
const list = document.querySelector ("#list" );
list.addEventListener ("click" , (event) => {
const btn = event.target.closest ("button[data-action]" );
if (!btn) {
console.log ("Клик мимо кнопок:" , event.target.tagName);
return ;
}
const li = btn.closest ("li" );
const name = li.querySelector (".name" ).textContent;
console.log (`Кнопка «${btn.dataset.action}» в строке «${name}»` );
});
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Қадами 2. Амалҳо
Акнун «хабаркашӣ»-ро бо рафтори воқеӣ иваз мекунем. ♥ синфи fav-и сатрро иваз мекунад (classList.toggle — аз дарси гузашта), ✕ тамоми сатрро нест мекунад.
Қадами 2 · Амалҳо · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< h4 > Покупки на базар</ h4 >
< ul id ="list" >
< li > < span class ="name" > Морковь</ span > < button data-action ="fav" title ="В избранное" > ♥</ button > < button data-action ="remove" title ="Удалить" > ✕</ button > </ li >
< li > < span class ="name" > Рис</ span > < button data-action ="fav" title ="В избранное" > ♥</ button > < button data-action ="remove" title ="Удалить" > ✕</ button > </ li >
< li > < span class ="name" > Лук</ span > < button data-action ="fav" title ="В избранное" > ♥</ button > < button data-action ="remove" title ="Удалить" > ✕</ button > </ li >
</ ul >
< p id ="count" > </ p >
h4 { margin : 0 0 8px ; }
ul { list-style : none; padding : 0 ; margin : 0 ; max-width : 340px ; }
li { display : flex; gap : 8px ; align-items : center; padding : 8px 10px ; border : 1px solid #e4e7ec ; border-radius : 10px ; margin-bottom : 6px ; }
.name { flex : 1 ; }
button { font : inherit; border : 1px solid #d0d5dd ; background : #fff ; border-radius : 8px ; cursor : pointer; padding : 2px 8px ; }
li.fav { background : #fef3f2 ; border-color : #fda29b ; }
li.fav .name { font-weight : 700 ; color : #b42318 ; }
li.fav [data-action="fav" ] { color : #d92d20 ; }
#count { color : #667085 ; font-size : 14px ; }
const list = document.querySelector ("#list" );
list.addEventListener ("click" , (event) => {
const btn = event.target.closest ("button[data-action]" );
if (!btn) return ; // клик берун аз тугмаҳо
const li = btn.closest ("li" );
if (btn.dataset.action === "fav" ) {
li.classList.toggle ("fav" ); // синф ҳаст — мебардорад, нест — илова мекунад
} else if (btn.dataset.action === "remove" ) {
li.remove ();
}
});
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Қадами 3. Ҳисобкунак ва бандҳои нав
Функсияи updateCount-ро илова мекунем ва баъди ҳар тағйир — ва як маротиба дар оғоз — даъват мекунем. Тугмаи «Добавить» банд бо функсияи makeItem месозад. Диққат диҳед: ягон обунаи нав барои бандҳои нав нест — вакилкунӣ ҳама чизро аллакай медонад.
Қадами 3 · Ҳисобкунак · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< h4 > Покупки на базар</ h4 >
< button id ="add" > + Добавить пункт</ button >
< ul id ="list" >
< li > < span class ="name" > Морковь</ span > < button data-action ="fav" title ="В избранное" > ♥</ button > < button data-action ="remove" title ="Удалить" > ✕</ button > </ li >
< li > < span class ="name" > Рис</ span > < button data-action ="fav" title ="В избранное" > ♥</ button > < button data-action ="remove" title ="Удалить" > ✕</ button > </ li >
< li > < span class ="name" > Лук</ span > < button data-action ="fav" title ="В избранное" > ♥</ button > < button data-action ="remove" title ="Удалить" > ✕</ button > </ li >
</ ul >
< p id ="count" > </ p >
h4 { margin : 0 0 8px ; }
ul { list-style : none; padding : 0 ; margin : 8px 0 ; max-width : 340px ; }
li { display : flex; gap : 8px ; align-items : center; padding : 8px 10px ; border : 1px solid #e4e7ec ; border-radius : 10px ; margin-bottom : 6px ; }
.name { flex : 1 ; }
button { font : inherit; border : 1px solid #d0d5dd ; background : #fff ; border-radius : 8px ; cursor : pointer; padding : 2px 8px ; }
li.fav { background : #fef3f2 ; border-color : #fda29b ; }
li.fav .name { font-weight : 700 ; color : #b42318 ; }
li.fav [data-action="fav" ] { color : #d92d20 ; }
#count { color : #667085 ; font-size : 14px ; }
const list = document.querySelector ("#list" );
const count = document.querySelector ("#count" );
const extras = ["Зира" , "Помидоры" , "Масло" , "Чой" ];
let next = 0 ;
function updateCount () {
const total = list.children.length;
const favs = list.querySelectorAll ("li.fav" ).length;
count.textContent = `Всего: ${total}, избранных: ${favs}` ;
}
function makeItem (text) {
const li = document.createElement ("li" );
li.innerHTML = `<span class="name"></span>
<button data-action="fav" title="В избранное">♥</button>
<button data-action="remove" title="Удалить">✕</button>` ;
li.querySelector (".name" ).textContent = text; // матн — танҳо тавассути textContent
return li;
}
list.addEventListener ("click" , (event) => {
const btn = event.target.closest ("button[data-action]" );
if (!btn) return ;
const li = btn.closest ("li" );
if (btn.dataset.action === "fav" ) li.classList.toggle ("fav" );
else if (btn.dataset.action === "remove" ) li.remove ();
updateCount ();
});
document.querySelector ("#add" ).addEventListener ("click" , () => {
list.append (makeItem (extras[next++ % extras.length]));
updateCount ();
});
updateCount ();
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Аз амалиёт чиро бояд дар хотир дошт
Коркардкунанда танҳо барои «чӣ заданд» масъул аст. Функсияи умумии updateCount танҳо барои «аз нав ҳисоб кардан ва нишон додан» масъул аст. Чунин тақсимот кодро хонданбоб мекунад — ва маҳз он дар лоиҳаҳои калон шуморо интизор аст (дарси 11 — ҳолати барнома).
Амалиёт: худатон ҷамъ кунед
ВАЗИФАИ 8.1 Рӯйхат бо интихобшуда ва ҳисобкунак миёна
Қадами 3-ро бе ишора такрор кунед, аммо аллакай худатон. Лозиманд: функсияи updateCount (ба #count «Всего: N, избранных: M» менависад), як коркардкунандаи клик дар #list (♥ синфи fav-ро иваз мекунад, ✕ сатрро нест мекунад) ва даъвати updateCount() дар ҷойҳои лозимӣ. Блоки «автотест» дар поён худаш ба тугмаҳо «клик мекунад», аз ҷумла ба банди нав, ки баъдтар илова шудааст, — онро тағйир надиҳед.
Амалиёт · Рӯйхат бо интихобшуда · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< ul id ="list" >
< li > < span class ="name" > Морковь</ span > < button data-action ="fav" > ♥</ button > < button data-action ="remove" > ✕</ button > </ li >
< li > < span class ="name" > Рис</ span > < button data-action ="fav" > ♥</ button > < button data-action ="remove" > ✕</ button > </ li >
< li > < span class ="name" > Лук</ span > < button data-action ="fav" > ♥</ button > < button data-action ="remove" > ✕</ button > </ li >
</ ul >
< p id ="count" > </ p >
ul { list-style : none; padding : 0 ; margin : 0 0 8px ; max-width : 340px ; }
li { display : flex; gap : 8px ; align-items : center; padding : 6px 10px ; border : 1px solid #e4e7ec ; border-radius : 10px ; margin-bottom : 6px ; }
.name { flex : 1 ; }
button { font : inherit; border : 1px solid #d0d5dd ; background : #fff ; border-radius : 8px ; cursor : pointer; padding : 2px 8px ; }
li.fav { background : #fef3f2 ; border-color : #fda29b ; }
li.fav .name { font-weight : 700 ; color : #b42318 ; }
const list = document.querySelector ("#list" );
const count = document.querySelector ("#count" );
function updateCount () {
// коди шумо инҷо
}
// коди шумо инҷо: ЯК коркардкунандаи клик дар list
updateCount ();
// ===== автотест: тағйир надиҳед =====
{
const q = (s) => document.querySelector (s);
const state = () => console.log (q ("#count" ).textContent);
q ('#list li:nth-child(1) [data-action="fav"]' ).click ();
q ('#list li:nth-child(3) [data-action="fav"]' ).click ();
state ();
q ('#list li:nth-child(2) [data-action="remove"]' ).click ();
state ();
q ('#list li:nth-child(1) [data-action="fav"]' ).click ();
state ();
q ("#list .name" ).click (); // клик берун аз тугмаҳо чизеро тағйир намедиҳад
q ("#list" ).click ();
state ();
const li = document.createElement ("li" ); // банде, ки баъдтар илова шуд
li.innerHTML = '<span class="name">Зира</span> <button data-action="fav">♥</button> <button data-action="remove">✕</button>' ;
q ("#list" ).append (li);
li.querySelector ('[data-action="fav"]' ).click ();
state ();
}
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Натиҷаи интизоршаванда Всего: 3, избранных: 2
Всего: 2, избранных: 2
Всего: 2, избранных: 1
Всего: 2, избранных: 1
Всего: 3, избранных: 2
Ишора 1 Ҳисобкунак: list.children.length — ҳамаи сатрҳо, list.querySelectorAll("li.fav").length — интихобшудаҳо. Матн — бо сатри қолабӣ дар count.textContent.
Ишора 2 Коркардкунанда: const btn = event.target.closest("button[data-action]"); if (!btn) return;, баъд const li = btn.closest("li"); ва ду шоха аз рӯи btn.dataset.action. Дар охири коркардкунанда — updateCount().
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
09 Вазифаи хонагӣ: рӯйхати интерактивӣ
«Компоненти интерактивӣ»-и худро ба итмом расонед: рӯйхат бо илова , нест кардан ва филтр бо тугмаҳо . Мавзӯъро худатон интихоб кунед: харидҳо, корҳои ҳафта, филмҳо барои тамошо, ҷойҳои дӯстдоштаи Душанбе. Натиҷаи ин вазифаи хонагӣ дар лоиҳаи хурд дар дарси 12 лозим мешавад.
Чӣ бояд ҳосил шавад
Шакли илова. Майдон ва тугма; банд ҳам бо клик, ҳам бо Enter илова мешавад (ҳодисаи submit, preventDefault). Баъди илова майдон тоза мешавад.
Санҷишҳо. Номи холӣ (баъди trim()) ва такроркунӣ (бе ҳисоби регистр) илова намешаванд.
Тугмаҳо дар ҳар сатр: ♥ — ба интихобшуда (синфи fav), ✕ — нест кардан. Ҳама тавассути як коркардкунанда дар рӯйхат: closest + data-action.
Филтр. Ду тугмаи «Все» ва «Избранные» (низ бо вакилкунӣ дар контейнери тугмаҳо). Тугмаи интихобшуда равшан шудааст. Филтр баъди илова, нест кардан ва иваз кардани ♥ кор карданро давом медиҳад.
Ҳисобкунаки «Всего: N, избранных: M».
Тозагӣ. Дар HTML onclick="…" нест. Ба ҳар li обуна нест. Матни корбар тавассути textContent ворид мешавад, на innerHTML.
Дар зер — тайёрии оғозии қуттии санҷиш бо автотест: он санҷишҳои маъмулиро такрор мекунад (илова, воридкунии холӣ, такроркунӣ, интихобшуда, филтр, нест кардан). Вақте дар консол ҳама мувофиқат кард — нусхаи худро бо мавзӯъ ва услубҳои зебо супоред.
Амалиёт: тайёрӣ барои вазифаи хонагӣ
ВАЗИФАИ 9.1 Рӯйхати интерактивӣ: илова, нест, филтр душвор
Ҷойи «коди шумо инҷо»-ро пур кунед: шакл, як коркардкунанда дар рӯйхат, яке — дар тугмаҳои филтр, функсияҳои applyFilter ва updateCount. Автотести поёнро тағйир надиҳед.
Вазифаи хонагӣ · Рӯйхати интерактивӣ · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< form id ="add-form" >
< input id ="new-item" placeholder ="Что купить?" autocomplete ="off" >
< button > Добавить</ button >
</ form >
< div id ="filters" >
< button data-filter ="all" class ="on" > Все</ button >
< button data-filter ="fav" > Избранные</ button >
</ div >
< ul id ="list" >
< li > < span class ="name" > Морковь</ span > < button data-action ="fav" > ♥</ button > < button data-action ="remove" > ✕</ button > </ li >
< li > < span class ="name" > Рис</ span > < button data-action ="fav" > ♥</ button > < button data-action ="remove" > ✕</ button > </ li >
</ ul >
< p id ="count" > </ p >
form, #filters { display : flex; gap : 6px ; margin-bottom : 8px ; }
input { font : inherit; padding : 6px 10px ; border : 1px solid #d0d5dd ; border-radius : 8px ; }
button { font : inherit; border : 1px solid #d0d5dd ; background : #fff ; border-radius : 8px ; cursor : pointer; padding : 2px 10px ; }
#filters .on { background : #1d2939 ; color : #fff ; }
ul { list-style : none; padding : 0 ; margin : 0 0 8px ; max-width : 360px ; }
li { display : flex; gap : 8px ; align-items : center; padding : 6px 10px ; border : 1px solid #e4e7ec ; border-radius : 10px ; margin-bottom : 6px ; }
li[hidden] { display : none; }
.name { flex : 1 ; }
li.fav { background : #fef3f2 ; border-color : #fda29b ; }
li.fav .name { font-weight : 700 ; color : #b42318 ; }
const form = document.querySelector ("#add-form" );
const input = document.querySelector ("#new-item" );
const filters = document.querySelector ("#filters" );
const list = document.querySelector ("#list" );
const count = document.querySelector ("#count" );
let currentFilter = "all" ;
function makeItem (text) {
const li = document.createElement ("li" );
li.innerHTML = `<span class="name"></span>
<button data-action="fav">♥</button>
<button data-action="remove">✕</button>` ;
li.querySelector (".name" ).textContent = text;
return li;
}
function updateCount () {
// коди шумо инҷо: «Всего: N, избранных: M»
}
function applyFilter () {
// коди шумо инҷо: пинҳон мекунем (li.hidden = true) он чизеро, ки ба currentFilter мувофиқ нест
}
// коди шумо инҷо:
// 1) submit-и шакл: preventDefault, trim, холӣ ва такрор (бе ҳисоби регистр) — илова накунед, вагарна append(makeItem(...)) ва тоза кардани майдон
// 2) ЯК click дар list: ♥ — toggle "fav", ✕ — remove
// 3) ЯК click дар filters: филтрро дар хотир доштан (data-filter), тугмаро бо синфи "on" равшан кардан
// баъди ҳар тағйир — applyFilter() ва updateCount()
applyFilter ();
updateCount ();
// ===== автотест: тағйир надиҳед =====
{
const q = (s) => document.querySelector (s);
const items = () => [... document.querySelectorAll ("#list li" )];
const visible = () => items ().filter ((li) => !li.hidden).length;
const add = (text) => {
q ("#new-item" ).value = text;
q ("#add-form" ).dispatchEvent (new Event ("submit" , { cancelable: true }));
};
add ("Лук" );
add (" " );
add ("лук" );
add ("Зира" );
console.log ("Всего: " + items ().length);
q ('#list li:nth-child(1) [data-action="fav"]' ).click ();
q ('#list li:nth-child(3) [data-action="fav"]' ).click ();
console.log ("Избранных: " + document.querySelectorAll ("#list li.fav" ).length);
q ('[data-filter="fav"]' ).click ();
console.log ("В фильтре «Избранные»: " + visible ());
q ('#list li:nth-child(1) [data-action="fav"]' ).click ();
console.log ("После снятия: " + visible ());
q ('[data-filter="all"]' ).click ();
q ('#list li:nth-child(2) [data-action="remove"]' ).click ();
console.log ("После удаления: " + items ().length + ", видно " + visible ());
console.log ("Поле очищено: " + (q ("#new-item" ).value === "" ));
console.log (q ("#count" ).textContent);
}
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Натиҷаи интизоршаванда Всего: 4
Избранных: 2
В фильтре «Избранные»: 2
После снятия: 1
После удаления: 3, видно 3
Поле очищено: true
Всего: 3, избранных: 1
Ишора 1 Аз шакл оғоз кунед: form.addEventListener("submit", (event) => { event.preventDefault(); … }). Такрор: [...list.querySelectorAll(".name")].some(n => n.textContent.toLowerCase() === text.toLowerCase()).
Ишора 2 applyFilter: барои ҳар li — li.hidden = currentFilter === "fav" && !li.classList.contains("fav");. Фаромӯш накунед, ки applyFilter()-ро баъди ♥, ✕ ва илова даъват кунед: вагарна дар филтри «Избранные» дили бардошташуда сатрро пинҳон намекунад.
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
Чиро супорид
Папка бо index.html, style.css, script.js — бо истинод ба репозиторий GitHub ё бо архив ба гурӯҳи Telegram. Номи мавзӯъро дар паём нависед.
Скриншоти рӯйхати кор карда истода (бо бандҳои иловашуда, филтри фаъолшуда).
Файли prompts.md (ё бахш дар README) бо ду чиз: (1) гузориши хатои шумо барои ЗС аз рӯи қолаби бахши 07 — аз рӯи хатои воқеӣ, ки ба шумо рӯ ба рӯ шуд; (2) як банд: ЗС чӣ маслиҳат дод ва аз он чиро шумо нагирифтед ва чаро.
Чӣ тавр баҳо медиҳем (0–10)
Меъёр Холҳо Чиро мебинем Шакл 2 submit + preventDefault, Enter кор мекунад, холӣ ва такрор рад мешаванд, майдон тоза мешавадВакилкунӣ 3 Як коркардкунанда дар рӯйхат, closest, data-action; бандҳои нав бе обунаҳои иловагӣ кор мекунанд Филтр 2 «Все» / «Избранные», равшан кардани тугмаи фаъол, филтр баъди тағйирот зинда мемонад Ҳисобкунак 1 Ҳамеша ададҳои дурустро нишон медиҳад Тозагии код 1 Коркардкунандаҳои inline нестанд, барои воридот textContent ба ҷои innerHTML, номҳои фаҳмо, такрор нест Қисми ЗС 1 Гузориши хато аз рӯи қолаб ва таҳлили боинсофонаи ҷавоби ЗС
Бонус (ихтиёрӣ, бе хол): клики дучанда ба ном онро иваз мекунад, клавишаи Escape майдонро тоза мекунад, Delete сатри охиринро нест мекунад.
Ёдрасӣ
Ҳангоми санҷиши вазифаи хонагӣ омӯзгор метавонад хоҳиш кунад, ки ҳар сатрро шарҳ диҳед. Агар шарҳ дода наметавонед, ки клик ба ✕ чӣ тавр ба коркардкунанда дар рӯйхат мерасад, — пеш аз супурдан бахшҳои 05 ва 06-ро аз нав хонед.
Ёддошти дарс
Ҳодиса — сигнал аз браузер. Коркардкунанда — функсияе, ки мо медиҳем (бе қавс!): el.addEventListener("click", handler).
Коркардкунандаҳо метавонанд бисёр бошанд, онҳо бо тартиби илова шудан кор мекунанд. Гирифтан: removeEventListener (ҳамон функсия лозим аст). Як маротиба: { once: true }. Хосияти onclick танҳо як коркардкунандаро нигоҳ медорад — истифода намебарем.
Коркардкунанда event мегирад: type, target (дар куҷо рух дод), currentTarget (дар куҷо коркардкунанда овезон аст), key, clientX/Y, target.value.
Ҳодисаҳои маъмул: click, input (ҳар ҳарф), change (қимат собит шуд), keydown, submit, DOMContentLoaded. Дар байрақча checked-ро мехонем, дар майдон ва рӯйхат — value (сатр).
Аз код: el.click(), el.dispatchEvent(new Event("input", { bubbles: true })), form.dispatchEvent(new Event("submit", { cancelable: true })). Ҳодисаҳои дастӣ ба таври пешфарз боло намераванд.
event.preventDefault() амали браузерро бекор мекунад: гузариш аз истинод, аз нав бор шудан ҳангоми submit, Ctrl + S. Шаклҳоро аз рӯи submit мешунавем, на аз рӯи клик ба тугма.
Болоравӣ: ҳодиса аз ҳадаф ба боло аз болои падарон меравад (button → li → ul → body). target тағйир намеёбад, currentTarget тағйир меёбад. Фурӯравӣ — { capture: true }, кам лозим аст.
stopPropagation() болоравиро қатъ мекунад — эҳтиёткорона истифода баред; бештар санҷидани event.target === event.currentTarget кифоя аст.
Вакилкунӣ: як коркардкунанда дар падар + event.target.closest("селектор") + if (!el) return. Барои элементҳои баъдтар иловашуда кор мекунад. Нишонаҳо дар HTML — data-action, data-id, мехонем el.dataset.action.
Боло намераванд: focus, blur, mouseenter, mouseleave — дар падар focusin, focusout, mouseover, mouseout-ро бишнавед.
Матни корбар дар DOM — тавассути textContent, на тавассути innerHTML.
Бо ЗС: гузориши хато = интизор будам / гирифтам (хато айнан) / коди ҳадди аққал (то 20 сатр) / чӣ кӯшиш кардам / формати ҷавоб. Фарзияҳоро як-як санҷед.