27 KiB
टेरारियम प्रोजेक्ट भाग 3: DOM मैनिपुलेशन और एक क्लोजर
स्केच नोट टोमोमी इमुरा द्वारा
प्री-लेक्चर क्विज़
परिचय
DOM, या "डॉक्यूमेंट ऑब्जेक्ट मॉडल", को मैनिपुलेट करना वेब डेवलपमेंट का एक महत्वपूर्ण पहलू है। MDN के अनुसार, "डॉक्यूमेंट ऑब्जेक्ट मॉडल (DOM) वेब पर किसी डॉक्यूमेंट की संरचना और सामग्री को बनाने वाले ऑब्जेक्ट्स का डेटा प्रतिनिधित्व है।" वेब पर DOM मैनिपुलेशन से जुड़ी चुनौतियां अक्सर जावास्क्रिप्ट फ्रेमवर्क का उपयोग करने का कारण रही हैं, लेकिन हम इसे वैनिला जावास्क्रिप्ट के साथ प्रबंधित करेंगे!
इसके अलावा, इस पाठ में जावास्क्रिप्ट क्लोजर का विचार पेश किया जाएगा, जिसे आप एक ऐसी फ़ंक्शन के रूप में सोच सकते हैं जो किसी अन्य फ़ंक्शन के अंदर बंद है, जिससे आंतरिक फ़ंक्शन को बाहरी फ़ंक्शन के स्कोप तक पहुंच मिलती है।
जावास्क्रिप्ट क्लोजर एक व्यापक और जटिल विषय है। यह पाठ केवल इस बुनियादी विचार को छूता है कि इस टेरारियम के कोड में, आपको एक क्लोजर मिलेगा: एक आंतरिक फ़ंक्शन और एक बाहरी फ़ंक्शन इस तरह से निर्मित होते हैं कि आंतरिक फ़ंक्शन को बाहरी फ़ंक्शन के स्कोप तक पहुंच मिलती है। इस पर अधिक जानकारी के लिए विस्तृत दस्तावेज़ देखें।
हम DOM को मैनिपुलेट करने के लिए एक क्लोजर का उपयोग करेंगे।
DOM को एक पेड़ के रूप में सोचें, जो यह दर्शाता है कि वेब पेज डॉक्यूमेंट को कितने तरीकों से मैनिपुलेट किया जा सकता है। विभिन्न APIs (एप्लिकेशन प्रोग्राम इंटरफेस) लिखे गए हैं ताकि प्रोग्रामर अपनी पसंद की प्रोग्रामिंग भाषा का उपयोग करके DOM तक पहुंच सकें और इसे संपादित, बदल, पुनः व्यवस्थित और अन्य तरीकों से प्रबंधित कर सकें।
DOM और उससे जुड़े HTML मार्कअप का एक प्रतिनिधित्व। ओल्फा नस्रौई से
इस पाठ में, हम अपने इंटरैक्टिव टेरारियम प्रोजेक्ट को पूरा करेंगे, जिसमें जावास्क्रिप्ट का उपयोग करके उपयोगकर्ता को पेज पर पौधों को मैनिपुलेट करने की अनुमति दी जाएगी।
पूर्वापेक्षा
आपके टेरारियम के लिए HTML और CSS तैयार होना चाहिए। इस पाठ के अंत तक, आप पौधों को टेरारियम में खींचने और बाहर निकालने में सक्षम होंगे।
कार्य
अपने टेरारियम फ़ोल्डर में एक नई फ़ाइल बनाएं जिसका नाम script.js
हो। उस फ़ाइल को <head>
सेक्शन में इंपोर्ट करें:
<script src="./script.js" defer></script>
नोट: HTML फ़ाइल को पूरी तरह से लोड होने के बाद ही जावास्क्रिप्ट को निष्पादित करने की अनुमति देने के लिए
defer
का उपयोग करें। आपasync
एट्रिब्यूट का भी उपयोग कर सकते हैं, जो स्क्रिप्ट को HTML फ़ाइल के पार्सिंग के दौरान निष्पादित करने की अनुमति देता है, लेकिन हमारे मामले में, यह महत्वपूर्ण है कि ड्रैग स्क्रिप्ट को निष्पादित करने से पहले HTML तत्व पूरी तरह से उपलब्ध हों।
DOM तत्व
सबसे पहले आपको उन तत्वों के संदर्भ बनाने की आवश्यकता है जिन्हें आप DOM में मैनिपुलेट करना चाहते हैं। हमारे मामले में, ये 14 पौधे हैं जो वर्तमान में साइड बार में प्रतीक्षा कर रहे हैं।
कार्य
dragElement(document.getElementById('plant1'));
dragElement(document.getElementById('plant2'));
dragElement(document.getElementById('plant3'));
dragElement(document.getElementById('plant4'));
dragElement(document.getElementById('plant5'));
dragElement(document.getElementById('plant6'));
dragElement(document.getElementById('plant7'));
dragElement(document.getElementById('plant8'));
dragElement(document.getElementById('plant9'));
dragElement(document.getElementById('plant10'));
dragElement(document.getElementById('plant11'));
dragElement(document.getElementById('plant12'));
dragElement(document.getElementById('plant13'));
dragElement(document.getElementById('plant14'));
यहां क्या हो रहा है? आप डॉक्यूमेंट का संदर्भ ले रहे हैं और उसके DOM में एक विशेष Id वाले तत्व को खोज रहे हैं। याद रखें कि HTML पर पहले पाठ में आपने प्रत्येक पौधे की छवि को व्यक्तिगत Ids (id="plant1"
) दिए थे? अब आप उस प्रयास का उपयोग करेंगे। प्रत्येक तत्व की पहचान करने के बाद, आप उस आइटम को dragElement
नामक एक फ़ंक्शन में पास करते हैं जिसे आप अभी बनाने वाले हैं। इस प्रकार, HTML में तत्व अब ड्रैग-इनेबल्ड हो गया है, या जल्द ही हो जाएगा।
✅ हम तत्वों को Id से क्यों संदर्भित करते हैं? CSS क्लास से क्यों नहीं? इस प्रश्न का उत्तर देने के लिए आप CSS पर पिछले पाठ का संदर्भ ले सकते हैं।
क्लोजर
अब आप dragElement
क्लोजर बनाने के लिए तैयार हैं, जो एक बाहरी फ़ंक्शन है जो एक या अधिक आंतरिक फ़ंक्शनों को संलग्न करता है (हमारे मामले में, तीन होंगे)।
क्लोजर तब उपयोगी होते हैं जब एक या अधिक फ़ंक्शनों को बाहरी फ़ंक्शन के स्कोप तक पहुंच की आवश्यकता होती है। यहां एक उदाहरण है:
function displayCandy(){
let candy = ['jellybeans'];
function addCandy(candyType) {
candy.push(candyType)
}
addCandy('gumdrops');
}
displayCandy();
console.log(candy)
इस उदाहरण में, displayCandy
फ़ंक्शन एक फ़ंक्शन को घेरता है जो पहले से मौजूद एक ऐरे में एक नई कैंडी प्रकार को पुश करता है। यदि आप इस कोड को चलाते हैं, तो candy
ऐरे अनिर्धारित होगा, क्योंकि यह एक स्थानीय वेरिएबल है (क्लोजर के लिए स्थानीय)।
✅ आप candy
ऐरे को कैसे सुलभ बना सकते हैं? इसे क्लोजर के बाहर ले जाकर देखें। इस तरह, ऐरे ग्लोबल हो जाएगा, बजाय इसके कि यह केवल क्लोजर के स्थानीय स्कोप में उपलब्ध हो।
कार्य
script.js
में तत्व घोषणाओं के नीचे एक फ़ंक्शन बनाएं:
function dragElement(terrariumElement) {
//set 4 positions for positioning on the screen
let pos1 = 0,
pos2 = 0,
pos3 = 0,
pos4 = 0;
terrariumElement.onpointerdown = pointerDrag;
}
dragElement
को इसका terrariumElement
ऑब्जेक्ट स्क्रिप्ट के शीर्ष पर घोषणाओं से मिलता है। फिर, आप उस फ़ंक्शन में पास किए गए ऑब्जेक्ट के लिए कुछ स्थानीय पोजीशन को 0
पर सेट करते हैं। ये स्थानीय वेरिएबल्स हैं जिन्हें आप प्रत्येक तत्व के लिए मैनिपुलेट करेंगे क्योंकि आप क्लोजर के भीतर ड्रैग और ड्रॉप कार्यक्षमता जोड़ते हैं। टेरारियम इन खींचे गए तत्वों से भरा जाएगा, इसलिए एप्लिकेशन को यह ट्रैक रखना होगा कि उन्हें कहां रखा गया है।
इसके अलावा, terrariumElement
जिसे इस फ़ंक्शन में पास किया गया है, को एक pointerdown
इवेंट सौंपा गया है, जो वेब APIs का हिस्सा है जो DOM प्रबंधन में मदद करने के लिए डिज़ाइन किया गया है। onpointerdown
तब फायर होता है जब कोई बटन दबाया जाता है, या हमारे मामले में, एक ड्रैग करने योग्य तत्व को छुआ जाता है। यह इवेंट हैंडलर वेब और मोबाइल ब्राउज़रों दोनों पर काम करता है, कुछ अपवादों के साथ।
✅ इवेंट हैंडलर onclick
में क्रॉस-ब्राउज़र अधिक समर्थन है; आप इसे यहां क्यों नहीं उपयोग करेंगे? उस सटीक प्रकार की स्क्रीन इंटरैक्शन के बारे में सोचें जिसे आप यहां बनाना चाहते हैं।
पॉइंटरड्रैग फ़ंक्शन
terrariumElement
को इधर-उधर खींचने के लिए तैयार है; जब onpointerdown
इवेंट फायर होता है, तो pointerDrag
फ़ंक्शन को बुलाया जाता है। इस लाइन के ठीक नीचे वह फ़ंक्शन जोड़ें: terrariumElement.onpointerdown = pointerDrag;
:
कार्य
function pointerDrag(e) {
e.preventDefault();
console.log(e);
pos3 = e.clientX;
pos4 = e.clientY;
}
कई चीजें होती हैं। सबसे पहले, आप e.preventDefault();
का उपयोग करके सामान्य घटनाओं को रोकते हैं जो आमतौर पर pointerdown
पर होती हैं। इस तरह आपके पास इंटरफ़ेस के व्यवहार पर अधिक नियंत्रण होता है।
जब आपने स्क्रिप्ट फ़ाइल को पूरी तरह से बना लिया हो, तो इस लाइन पर वापस आएं और इसे बिना
e.preventDefault()
के आज़माएं - क्या होता है?
दूसरा, index.html
को एक ब्राउज़र विंडो में खोलें और इंटरफ़ेस का निरीक्षण करें। जब आप किसी पौधे पर क्लिक करते हैं, तो आप देख सकते हैं कि 'e' इवेंट कैसे कैप्चर किया गया है। इवेंट में कितनी जानकारी एकत्र की जाती है, यह देखने के लिए इवेंट को गहराई से देखें!
इसके बाद, ध्यान दें कि स्थानीय वेरिएबल्स pos3
और pos4
को e.clientX
पर कैसे सेट किया गया है। आप निरीक्षण पैन में e
मान पा सकते हैं। ये मान उस क्षण पौधे के x और y निर्देशांक को कैप्चर करते हैं जब आप उस पर क्लिक या टच करते हैं। आपको पौधों के व्यवहार पर बारीकी से नियंत्रण की आवश्यकता होगी क्योंकि आप उन्हें क्लिक और ड्रैग करते हैं, इसलिए आप उनके निर्देशांक को ट्रैक करते हैं।
✅ क्या यह अधिक स्पष्ट हो रहा है कि यह पूरा ऐप एक बड़े क्लोजर के साथ क्यों बनाया गया है? यदि ऐसा नहीं होता, तो आप 14 ड्रैग करने योग्य पौधों में से प्रत्येक के लिए स्कोप को कैसे बनाए रखते?
प्रारंभिक फ़ंक्शन को पूरा करने के लिए pos4 = e.clientY
के नीचे दो और पॉइंटर इवेंट मैनिपुलेशन जोड़ें:
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
अब आप यह संकेत दे रहे हैं कि आप पौधे को पॉइंटर के साथ खींचना चाहते हैं जैसे ही आप इसे हिलाते हैं, और खींचने की प्रक्रिया को रोकना चाहते हैं जब आप पौधे को अनचयनित करते हैं। onpointermove
और onpointerup
उसी API का हिस्सा हैं जैसे onpointerdown
। इंटरफ़ेस अब त्रुटियां फेंकेगा क्योंकि आपने अभी तक elementDrag
और stopElementDrag
फ़ंक्शंस को परिभाषित नहीं किया है, इसलिए उन्हें अगला बनाएं।
elementDrag
और stopElementDrag
फ़ंक्शंस
आप दो और आंतरिक फ़ंक्शंस जोड़कर अपने क्लोजर को पूरा करेंगे जो यह संभालेंगे कि जब आप पौधे को खींचते हैं और खींचना बंद करते हैं तो क्या होता है। आप जो व्यवहार चाहते हैं वह यह है कि आप किसी भी समय किसी भी पौधे को खींच सकें और उसे स्क्रीन पर कहीं भी रख सकें। यह इंटरफ़ेस काफी अनुकूल है (उदाहरण के लिए, कोई ड्रॉप ज़ोन नहीं है) ताकि आप अपने टेरारियम को अपनी पसंद के अनुसार डिज़ाइन कर सकें, पौधों को जोड़कर, हटाकर और पुनः स्थिति देकर।
कार्य
pointerDrag
के समापन कर्ली ब्रैकेट के ठीक बाद elementDrag
फ़ंक्शन जोड़ें:
function elementDrag(e) {
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
console.log(pos1, pos2, pos3, pos4);
terrariumElement.style.top = terrariumElement.offsetTop - pos2 + 'px';
terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px';
}
इस फ़ंक्शन में, आप उन प्रारंभिक पोजीशन्स 1-4 को बहुत अधिक संपादित करते हैं जिन्हें आपने बाहरी फ़ंक्शन में स्थानीय वेरिएबल्स के रूप में सेट किया था। यहां क्या हो रहा है?
जैसे ही आप खींचते हैं, आप pos1
को फिर से असाइन करते हैं, इसे pos3
(जिसे आपने पहले e.clientX
के रूप में सेट किया था) माइनस वर्तमान e.clientX
मान के बराबर बनाते हैं। आप pos2
के साथ एक समान ऑपरेशन करते हैं। फिर, आप pos3
और pos4
को तत्व के नए X और Y निर्देशांक पर रीसेट करते हैं। आप इन परिवर्तनों को कंसोल में खींचते समय देख सकते हैं। फिर, आप पौधे की css शैली को मैनिपुलेट करते हैं ताकि इसे नई पोजीशन पर सेट किया जा सके, जो pos1
और pos2
की नई पोजीशन के आधार पर पौधे के शीर्ष और बाएं X और Y निर्देशांक की गणना करता है।
offsetTop
औरoffsetLeft
CSS प्रॉपर्टीज़ हैं जो किसी तत्व की स्थिति को उसके पैरेंट के आधार पर सेट करती हैं; इसका पैरेंट कोई भी तत्व हो सकता है जोstatic
के रूप में पोजिशन नहीं किया गया हो।
यह सभी पोजीशनिंग की पुनर्गणना टेरारियम और उसके पौधों के व्यवहार को बारीकी से ट्यून करने की अनुमति देती है।
कार्य
इंटरफ़ेस को पूरा करने का अंतिम कार्य stopElementDrag
फ़ंक्शन को elementDrag
के समापन कर्ली ब्रैकेट के बाद जोड़ना है:
function stopElementDrag() {
document.onpointerup = null;
document.onpointermove = null;
}
यह छोटा फ़ंक्शन onpointerup
और onpointermove
इवेंट्स को रीसेट करता है ताकि आप या तो अपने पौधे की प्रगति को फिर से शुरू कर सकें या एक नया पौधा खींचना शुरू कर सकें।
✅ क्या होता है यदि आप इन इवेंट्स को null पर सेट नहीं करते?
अब आपने अपना प्रोजेक्ट पूरा कर लिया है!
🥇बधाई हो! आपने अपना सुंदर टेरारियम पूरा कर लिया है।
🚀चुनौती
अपने क्लोजर में एक नया इवेंट हैंडलर जोड़ें ताकि पौधों के साथ कुछ और किया जा सके; उदाहरण के लिए, किसी पौधे को सामने लाने के लिए उस पर डबल-क्लिक करें। रचनात्मक बनें!
पोस्ट-लेक्चर क्विज़
समीक्षा और स्व-अध्ययन
स्क्रीन पर तत्वों को खींचना तुच्छ लग सकता है, लेकिन इसे करने के कई तरीके हैं और कई समस्याएं हो सकती हैं, यह इस बात पर निर्भर करता है कि आप किस प्रकार का प्रभाव चाहते हैं। वास्तव में, एक पूरा ड्रैग और ड्रॉप API है जिसे आप आज़मा सकते हैं। हमने इस मॉड्यूल में इसका उपयोग नहीं किया क्योंकि हम जो प्रभाव चाहते थे वह थोड़ा अलग था, लेकिन इसे अपने प्रोजेक्ट पर आज़माएं और देखें कि आप क्या हासिल कर सकते हैं।
पॉइंटर इवेंट्स पर अधिक जानकारी W3C डॉक्स और MDN वेब डॉक्स पर पाएं।
हमेशा ब्राउज़र क्षमताओं की जांच CanIUse.com का उपयोग करके करें।
असाइनमेंट
अस्वीकरण:
यह दस्तावेज़ AI अनुवाद सेवा Co-op Translator का उपयोग करके अनुवादित किया गया है। जबकि हम सटीकता सुनिश्चित करने का प्रयास करते हैं, कृपया ध्यान दें कि स्वचालित अनुवाद में त्रुटियां या अशुद्धियां हो सकती हैं। मूल दस्तावेज़, जो इसकी मूल भाषा में है, को प्रामाणिक स्रोत माना जाना चाहिए। महत्वपूर्ण जानकारी के लिए, पेशेवर मानव अनुवाद की सिफारिश की जाती है। इस अनुवाद के उपयोग से उत्पन्न किसी भी गलतफहमी या गलत व्याख्या के लिए हम उत्तरदायी नहीं हैं।