Skip to content
This page has been auto-translated and may contain errors.View in English

ईवेंट्स

docs.scrimba.com

एक पेज जो कभी प्रतिक्रिया नहीं देता वह सिर्फ एक दस्तावेज़ है। जब आप चाहते हैं कि कोई बटन पर क्लिक करने पर, सर्च बॉक्स में टाइप करने पर, या फॉर्म सबमिट करने पर कुछ होना चाहिए, तो आपको कहने का एक तरीका चाहिए "जब यह होता है, तो यह कोड चलाएँ"। यही ईवेंट्स हैं। यह अध्याय उपयोगकर्ता द्वारा किए जाने वाले कामों को सुनने और उनके जवाब देने के बारे में है।

एक ईवेंट को सुनना

एक ईवेंट कुछ ऐसा है जो पेज पर होता है: एक क्लिक, एक की प्रेस, एक फॉर्म भेजा जाना। इसके जवाब में, आप एक एलिमेंट चुनते हैं, ईवेंट का नाम देते हैं जिसकी आपको परवाह है, और इसके होने पर चलाने के लिए एक फंक्शन हाथ में दे देते हैं।

वह फंक्शन हैंडलर कहलाता है। जो मेथड इसे जोड़ता है वह है addEventListener:

js
const button = document.querySelector(".buy-button");

button.addEventListener("click", () => {
  console.log("किसी ने खरीदारी बटन पर क्लिक किया");
});

बाएँ से दाएँ पढ़ें: इस बटन पर, "click" के लिए सुनें, और जब यह होता है, तो यह फंक्शन चलाएँ। हैंडलर हर बार चलता है जब ईवेंट होता है, एक बार नहीं। तीन बार क्लिक करें और यह तीन बार चलेगा।

एक ईवेंट एक सिग्नल है जो ब्राउज़र तब भेजता है जब कुछ होता है: उपयोगकर्ता क्लिक करता है, टाइप करता है, फॉर्म सबमिट करता है, या पेज लोडिंग खत्म करता है। आप addEventListener के साथ एक हैंडलर रजिस्टर करके जवाब देते हैं, जो ईवेंट का नाम एक स्ट्रिंग के रूप में लेता है और हर बार जब यह फायर होता है तो कॉल करने के लिए एक फंक्शन लेता है।

js
const button = document.querySelector(".buy-button");

const handleBuy = () => {
  console.log("किसी ने खरीदारी बटन पर क्लिक किया");
};

button.addEventListener("click", handleBuy);

ध्यान दें कि handleBuy को कोष्ठक के बिना पास किया जाता है। आप ब्राउज़र को फंक्शन ही दे रहे हैं ताकि वह इसे बाद में कॉल करे, अभी नहीं। addEventListener("click", handleBuy()) लिखने से यह तुरंत कॉल हो जाएगा और जो कुछ भी यह लौटाएगा वह रजिस्टर हो जाएगा, जो एक आम शुरुआती गलती है।

एक ईवेंट एक संदेश है जो ब्राउज़र किसी भी कोड को भेजता है जिसने इसमें रुचि रजिस्टर की है। आप addEventListener(type, handler) के साथ रजिस्टर करते हैं: type ईवेंट का नाम एक स्ट्रिंग के रूप में है, handler एक कॉलबैक है जो ब्राउज़र हर बार कॉल करता है जब ईवेंट उस एलिमेंट पर फायर होता है।

js
const button = document.querySelector(".buy-button");

const handleBuy = () => {
  console.log("किसी ने खरीदारी बटन पर क्लिक किया");
};

button.addEventListener("click", handleBuy);

यहाँ दो चीजें मायने रखती हैं। पहली, आप handleBuy पास करते हैं, फंक्शन वैल्यू, न कि handleBuy(), इसे कॉल करने का नतीजा। दूसरी, addEventListener योगात्मक है: इसे दो फंक्शन के साथ दो बार कॉल करें और दोनों चलते हैं, तो सुनने वाले स्टैक करते हैं बजाय ओवरराइट करने के। यही व्यावहारिक कारण है कि यह button.onclick असाइन करने की जगह मौजूद है, जो एक single हैंडलर रखता है और किसी भी पिछले को मिटा देता है। एक नाम वाला संदर्भ रखना भी बाद में मायने रखता है, जब आप इसे हटाना चाहते हैं।

हैंडलर सामान्य फंक्शन हैं, और जिन एलिमेंट्स को आप उन्हें अटैच करते हैं वे DOM से आते हैं। अगर आप एक एलिमेंट चुन सकते हैं और एक फंक्शन लिख सकते हैं, तो आप उपयोगकर्ता द्वारा इसे किए जाने वाले कामों के जवाब दे सकते हैं।

Junoएक ईवेंट को सुनना उपयोगकर्ता के जवाब में, एक एलिमेंट चुनें, ईवेंट को "click" जैसी स्ट्रिंग के रूप में नाम दें, और addEventListener को चलाने के लिए एक फंक्शन दें। वह फंक्शन हैंडलर है, और यह हर बार चलता है जब ईवेंट होता है, एक बार नहीं। यह एक मेथड लगभग सभी कुछ के पीछे है जो पेज आपके जवाब में करता है।
Junoएक ईवेंट को सुननाaddEventListener एक ईवेंट का नाम और एक फंक्शन लेता है, और हर बार जब ईवेंट फायर होता है तो उस फंक्शन को कॉल करता है। फंक्शन को नाम से कोष्ठक के बिना पास करें: handleBuy, न कि handleBuy()। कोष्ठक जोड़ने से यह तुरंत कॉल हो जाता है क्लिक के बजाय, और यह लगभग सभी को एक बार फंसाता है।
Junoएक ईवेंट को सुननाaddEventListener एक कॉलबैक रजिस्टर करता है जो ब्राउज़र हर मिलान करने वाले ईवेंट पर फायर करता है, और यह स्टैक करता है बजाय ओवरराइट करने के, यही कारण है कि आप इसे onclick पर पसंद करते हैं। फंक्शन वैल्यू पास करें, इसके कॉल परिणाम नहीं, तो handleBuy और कभी नहीं handleBuy()। एक नाम वाला संदर्भ भी रखें, क्योंकि आप इसे वापस चाहेंगे जब सुनने वाले को हटाने का समय हो।

ईवेंट ऑब्जेक्ट

जब ब्राउज़र आपके हैंडलर को चलाता है, तो यह इसे एक जानकारी देता है: एक ईवेंट ऑब्जेक्ट जो बताता है कि क्या हुआ। इसे अपने हैंडलर को एक पैरामीटर दे कर पकड़ें, आमतौर पर event नाम दिया जाता है:

js
const button = document.querySelector(".buy-button");

button.addEventListener("click", (event) => {
  console.log(event.target); // वह एलिमेंट जिस पर क्लिक किया गया
});

सबसे उपयोगी हिस्सा है event.target: वह एलिमेंट जिस पर ईवेंट हुआ। अगर क्लिक बटन पर था, तो event.target वह बटन है। आपको इसे दोबारा चुनना नहीं पड़ता, ईवेंट पहले से ही बताता है कि यह कहाँ से आया।

हर हैंडलर को एक argument मिलता है: ईवेंट ऑब्जेक्ट, जो बताता है कि क्या हुआ। आप इसे एक पैरामीटर का नाम देकर पकड़ते हैं, आमतौर पर event (या e):

js
const search = document.querySelector(".search-input");

search.addEventListener("input", (event) => {
  console.log(event.target.value); // उपयोगकर्ता द्वारा अब तक टाइप किया गया
});

event.target वह एलिमेंट है जिस पर ईवेंट फायर हुआ। फॉर्म फील्ड पर यह शो का स्टार है, क्योंकि event.target.value आपको इनपुट का वर्तमान टेक्स्ट देता है। वह जोड़ी, input ईवेंट प्लस event.target.value, यही है कि आप कैसे पढ़ते हैं कि कोई जब टाइप करता है तो क्या टाइप कर रहा है।

ब्राउज़र आपके हैंडलर को एक single argument पास करता है, ईवेंट ऑब्जेक्ट, जो क्या हुआ का एक स्नैपशॉट है: कौन सा एलिमेंट, कौन सी की, माउस की स्थिति, और ईवेंट के डिफ़ॉल्ट व्यवहार को नियंत्रित करने के लिए मेथड्स। आप इसे एक पैरामीटर के साथ पकड़ते हैं, आमतौर पर event

js
const search = document.querySelector(".search-input");

search.addEventListener("input", (event) => {
  console.log(event.target.value); // फील्ड में वर्तमान टेक्स्ट
});

event.target वह एलिमेंट है जिसने ईवेंट शुरू किया, जो हमेशा वह एलिमेंट नहीं है जिससे आपने सुनने वाले को अटैच किया (यह event.currentTarget है, और उनके बीच का अंतर यही है जो delegation को काम करता है, नीचे)। फॉर्म कंट्रोल्स पर, event.target.value वर्तमान वैल्यू को एक स्ट्रिंग के रूप में पढ़ता है, तो HTML जो टेक्स्ट के रूप में रखता है वही यहाँ टेक्स्ट के रूप में वापस आता है। एक नंबर के लिए पहुँचें और आप इसे Number(event.target.value) के साथ स्वयं कन्वर्ट करते हैं।

Junoईवेंट ऑब्जेक्ट आपके हैंडलर को एक argument मिलता है, ईवेंट ऑब्जेक्ट, तो इसे पकड़ने के लिए event नाम का एक पैरामीटर दें। जिस हिस्से के लिए आप सबसे ज्यादा पहुँचेंगे वह है event.target, वह एलिमेंट जिस पर ईवेंट हुआ। इसे दोबारा चुनने की कोई जरूरत नहीं, ईवेंट पहले से ही जानता है कि यह कहाँ से आया।
Junoईवेंट ऑब्जेक्टevent नाम का एक पैरामीटर दें और ब्राउज़र इसे क्या हुआ इसके विवरण के साथ भरता है। event.target वह एलिमेंट है जिस पर यह फायर हुआ, और एक इनपुट पर, event.target.value फील्ड में वर्तमान टेक्स्ट है। input ईवेंट को event.target.value के साथ जोड़ें और आप पढ़ सकते हैं कि कोई जब टाइप करता है तो क्या टाइप करता है।
Junoईवेंट ऑब्जेक्ट ईवेंट ऑब्जेक्ट जो हुआ इसका एक स्नैपशॉट है, और event.target वह है जहाँ से यह शुरू हुआ, जो हमेशा वह जगह नहीं है जहाँ आपने सुनने वाले को अटैच किया; वह event.currentTarget है। फॉर्म फील्ड पर event.target.value एक स्ट्रिंग के रूप में वापस आता है, तो जब आपको नंबर की जरूरत हो तो इसे Number(...) में लपेटें। target-बनाम-currentTarget split को ध्यान में रखें, क्योंकि delegation इस पर निर्भर करता है।

आम ईवेंट्स

कुछ ईवेंट्स लगभग सभी कुछ को कवर करते हैं जो आप बनाएँगे:

  • click: उपयोगकर्ता कुछ पर क्लिक या टैप करता है।
  • input: जब वे टाइप करते हैं तो टेक्स्ट फील्ड की वैल्यू बदलती है।
  • submit: एक फॉर्म भेजा जाता है।
  • keydown: एक की दबाई जाती है।

मुश्किल वाला है submit। डिफ़ॉल्ट रूप से, फॉर्म सबमिट करने से पेज रीलोड होता है, जो आपके JavaScript को मिटा देता है। इसे रोकने के लिए, हैंडलर के अंदर event.preventDefault() कॉल करें:

js
const form = document.querySelector("form");

form.addEventListener("submit", (event) => {
  event.preventDefault(); // पेज को रीलोड होने से रोकें
  console.log("फॉर्म सबमिट किया गया, पेज जहाँ है वहीं रहता है");
});

सबसे ज्यादा पेज एक छोटे सेट ईवेंट्स पर निर्भर करते हैं: click बटन के लिए, input टेक्स्ट फील्ड के लिए जब वे बदलते हैं, submit फॉर्म के लिए, और keydown कीबोर्ड शॉर्टकट के लिए। इन चार को सीखें और आप ज्यादातर इंटरएक्शन बना सकते हैं।

जो लोगों को फंसाता है वह है submit। फॉर्म का डिफ़ॉल्ट व्यवहार पेज रीलोड करना या दूर नेविगेट करना है, जो आपके कोड को जो संभाल रहा था उसे फेंक देता है। event.preventDefault() कॉल करें पेज को अपनी जगह पर रखने और स्वयं संभालने के लिए:

js
const form = document.querySelector("form");

const handleSubmit = (event) => {
  event.preventDefault();
  const email = form.querySelector(".email-input").value;
  console.log(`${email} के साथ साइन अप कर रहे हैं`);
};

form.addEventListener("submit", handleSubmit);

फॉर्म पर submit के लिए सुनें, बटन पर click के लिए नहीं, तो कीबोर्ड उपयोगकर्ता जो Enter दबाते हैं वे भी कवर किए जाते हैं।

चार ईवेंट्स ज्यादातर इंटरएक्शन को ले जाते हैं: click, input (हर वैल्यू परिवर्तन पर फायर होता है, change के विपरीत जो blur के लिए प्रतीक्षा करता है), submit, और keydown। उन्हें सही एलिमेंट से बाँधें और ज्यादातर UI इनसे बाहर आता है।

submit ईवेंट वह है जहाँ preventDefault अपनी जगह अर्जित करता है। फॉर्म का डिफ़ॉल्ट एक्शन एक पूर्ण नेविगेशन है, जो आपके इन-पेज state को फेंक देता है। event.preventDefault() कॉल करने से वह रद्द हो जाता है ताकि आप डेटा को स्वयं संभाल सकें:

js
const form = document.querySelector("form");

const handleSubmit = (event) => {
  event.preventDefault();
  const email = form.querySelector(".email-input").value;
  console.log(`${email} के साथ साइन अप कर रहे हैं`);
  // इसे किसी सर्वर को भेजना अगले अध्याय का काम है
};

form.addEventListener("submit", handleSubmit);

फॉर्म के submit को अटैच करें, बटन के click को नहीं: submit Enter की, बटन क्लिक के लिए, और प्रोग्राम्मैटिक सबमिशन के लिए भी फायर होता है, तो यह सही हुक है। एक बार जब आपके पास वैल्यू हो, तो इसे कहीं भेजना वह है जहाँ async कोड आता है, जो अगला अध्याय है।

Bubbling और delegation

जब आप किसी एलिमेंट पर क्लिक करते हैं, तो ईवेंट वहीं नहीं रुकता। यह bubbles करता है: यह क्लिक किए गए एलिमेंट पर फायर होता है, फिर इसके parent पर, फिर उस parent के parent पर, सभी तरह से ऊपर। यही कारण है कि parent पर एक सुनने वाला अपने children के क्लिक को सुनता है।

वह व्यवहार delegation को शक्ति देता है: एक parent को एक सुनने वाले को अटैच करें और event.target का उपयोग करके खोजें कि कौन सा child वास्तव में क्लिक किया गया। प्रति-item सुनने वाले के बजाय, आपको एक मिलता है जो सभी को कवर करता है।

js
const list = document.querySelector(".todo-list");

list.addEventListener("click", (event) => {
  if (event.target.matches(".delete")) {
    event.target.closest("li").remove();
  }
});

लाभ: यह सूची में बाद में जोड़े गए items को संभालता है। प्रति-item सुनने वाला केवल एलिमेंट्स को बाँधता है जो अभी मौजूद हैं; एक delegated सुनने वाला parent पर children के क्लिक को पकड़ता है जो मौजूद नहीं थे जब कोड चला, क्योंकि ईवेंट अभी भी parent तक bubble करता है जो सुन रहा है।

सुनने वाले को हटाना

removeEventListener एक हैंडलर को अलग करता है, लेकिन केवल अगर आप आमंत्रण दिए गए फंक्शन का बिल्कुल वही संदर्भ पास करते हैं:

js
const button = document.querySelector(".buy-button");

button.addEventListener("click", handleBuy);
button.removeEventListener("click", handleBuy); // काम करता है: वही संदर्भ

यही कारण है कि anonymous हैंडलर को हटाया नहीं जा सकता। addEventListener("click", () => {...}) जैसा एक inline arrow फंक्शन हर बार एक नया फंक्शन बनाता है, तो आपके पास removeEventListener को देने के लिए कोई संदर्भ नहीं है, और सुनने वाला फंसा हुआ है। Named हैंडलर जिन्हें आप हटाने की योजना बनाते हैं वह बचाते हैं। सुनने वाले जो उस एलिमेंट को आउटलाइव करते हैं जिन्हें वे छूते हैं वे memory leaks का एक असली स्रोत हैं, जहाँ ऑब्जेक्ट जिन्हें पेज को अब जरूरत नहीं है वे दावा नहीं किए जा सकते क्योंकि एक सुनने वाला अभी भी उन्हें इंगित करता है।

एक और performance नोट: scroll या touch सुनने वालों पर third argument के रूप में { passive: true } जोड़ना आपको preventDefault कॉल नहीं करने का वचन देता है, जो ब्राउज़र को आपके हैंडलर पर प्रतीक्षा किए बिना स्क्रॉल करने देता है और स्क्रॉलिंग को smooth रखता है।

Junoआम ईवेंट्स ईवेंट्स जिन्हें आप सबसे ज्यादा यूज़ करेंगे वे हैं click, input, submit, और keydown। जो एक याद रखना है वह है submit: एक फॉर्म डिफ़ॉल्ट रूप से पेज रीलोड करता है, तो हैंडलर में event.preventDefault() कॉल करें इसे रोकने के लिए और नियंत्रण रखें। इसे मिस करें और आपका पेज आपके नीचे रीफ्रेश होता है, जो पहली बार confusing है।
Junoआम ईवेंट्सclick, input, submit, और keydown ज्यादातर को कवर करते हैं जो आप बनाते हैं। फॉर्म पर submit के लिए सुनें, बटन पर click के लिए नहीं, तो Enter कीबोर्ड उपयोगकर्ताओं के लिए काम करता है। और submit हैंडलर में event.preventDefault() कॉल करें, अन्यथा पेज रीलोड होता है और अपने साथ state भी ले जाता है।
Junoआम ईवेंट्स ईवेंट्स parents तक bubble करते हैं, तो एक delegated सुनने वाला प्लस event.target कई children को कवर करता है, बाद में जोड़े गए ones सहित। removeEventListener को आपने जोड़ा था वही फंक्शन संदर्भ चाहिए, यही कारण है कि anonymous हैंडलर को कभी नहीं हटाया जा सकता और memory leak कर सकते हैं। और submit बटन के click को हराता है क्योंकि यह Enter के लिए भी फायर होता है; इसे reload रोकने के लिए event.preventDefault() वहीं रखें।

ईवेंट्स यहाँ से कहाँ जाते हैं

ईवेंट्स यह हैं कि एक पेज कैसे सुनता है। आप एक एलिमेंट चुनते हैं, नाम देते हैं कि आप किस बारे में परवाह करते हैं, और जब यह होता है तो एक फंक्शन चलाते हैं, ईवेंट ऑब्जेक्ट से विवरण पढ़ते हुए जब आप जाते हैं। लगभग हर interactive फीचर उस loop से बनाया जाता है।

प्राकृतिक अगला कदम हैंडलर में कुछ slow करना है, जैसे फॉर्म को किसी सर्वर को भेजना या fresh डेटा लोड करना, पेज को फ्रीज़ किए बिना। यही async कोड क्या है, और यह अगला अध्याय है। हैंडलर जो structured डेटा में पहुँचते हैं, जैसे items की एक सूची जो आप objects में रखते हैं, वह भी जिसे आप पहले से जानते हैं पर लीन करते हैं।