मैं एक आंतरिक HTML के अंदर क्लिक इवेंट कैसे प्राप्त कर सकता हूं?


12

मेरे पास यह लेआउट है जिसे गतिशील रूप से बनाया गया था:

for (let i = 1; i < 10; i++) {
  document.querySelector('.card-body').innerHTML += `<div class="row" id="img_div">
        <div class="col-12 col-sm-12 col-md-2 text-center">
          <img src="http://placehold.it/120x80" alt="prewiew" width="120" height="80">
        </div>
        <div id="text_div" class="col-12 text-sm-center col-sm-12 text-md-left col-md-6">
        <h4 class="name"><a href="#" id="title` + i + `">Name</a></h4>
          <h4>
            <small>state</small>
          </h4>
          <h4>
            <small>city</small>
          </h4>
          <h4>
            <small>zip</small>
          </h4>
        </div>
        <div class="col-12 col-sm-12 text-sm-center col-md-4 text-md-right row">
        </div>
      </div>
     `
  document.getElementById("title" + i).addEventListener('click', function() {
    console.log(i)
  });
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="card-body">
  <!-- person -->
</div>

और मैं घटना को प्रत्येक पर क्लिक करना चाहता हूं h4 class="name"और iसंबंधित संख्या के साथ एक लॉग दिखाता हूं ।

हालाँकि, console.logकेवल अंतिम iसंबंधित ( i=9इस मामले में) दिखाता है, और अन्य iसंख्याओं के साथ काम नहीं करता है । ऐसा क्यों होता है? मुझे क्या करना होगा?


3
शायद एचटीएमएल-स्ट्रिंग पास करने के बजाय Document.createElement () का उपयोग करें और आपके पास बहुत आसान समय होगा और मुझे लगता है कि आप अंत में बेहतर कोड के साथ समाप्त करेंगे।
प्रवेश

1
आपको अपने नोड्स के माध्यम से फिर से लूप करना होगा और एक घटना को संलग्न करना होगा जिसे आप एक स्ट्रिंग में संलग्न नहीं कर सकते हैं
यूजेन सन

अच्छा सवाल है, यह यकीन है कि के लिए मुश्किल है, मुझे लगता है कि यह एक घटना पोस्ट प्रतिपादन आकर्षित करने के लिए संभव हो सकता है .. उदाहरण के लिए अपने forपाश के बाद उन तत्वों को घटनाओं को लागू करने के लिए एक विधि बुला, लेकिन मुझे नहीं पता। परीक्षण करने के लिए jsField होगा।
पोग्रिंडिस

के लिए एक प्रत्यायोजित ईवेंट हैंडलर बनाया .card-bodyऔर जाँच की कि क्या तत्व ( target) एक एंकर और आईडी है जो साथ शुरू होता है title
23

1
आह, बस एक जवाब पोस्ट करने के बारे में। फिर से खोलने के लिए वोट दिया। क्लोज़र आवश्यक नहीं हैं, समस्या innerHTML += ...पहले से मौजूद ईवेंट श्रोताओं को मार रही है, न कि बंद करने की। document.createElementइसके बजाय उपयोग करें । इस धागे को
gorglen

जवाबों:


8

innerHTMLपूर्ण HTML को फिर से बनाता है, जिसके परिणामस्वरूप पहले से जुड़ी सभी घटनाएं खो जाती हैं। उपयोगinsertAdjacentHTML()

for(let i=1;i<10;i++){
    document.querySelector('.card-body').insertAdjacentHTML('beforeend',`<div class="row" id="img_div">
        <div class="col-12 col-sm-12 col-md-2 text-center">
          <img src="http://placehold.it/120x80" alt="prewiew" width="120" height="80">
        </div>
        <div id="text_div" class="col-12 text-sm-center col-sm-12 text-md-left col-md-6">
        <h4 class="name"><a href="#" id="title`+i+`">Name</a></h4>
          <h4>
            <small>state</small>
          </h4>
          <h4>
            <small>city</small>
          </h4>
          <h4>
            <small>zip</small>
          </h4>
        </div>
        <div class="col-12 col-sm-12 text-sm-center col-md-4 text-md-right row">
        </div>
      </div>
     `);
   document.getElementById("title"+i).addEventListener('click', function () {
    console.log(i)
  });
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="card-body">
<!-- person -->
</div>


3
वाह .. मैं simular चीजों के साथ खिलवाड़ कर रहा हूं और कभी भी एक बार नहीं आया insertAdjacentHTML- हर दिन एक schoolday, वास्तव में अच्छा।
पोग्रिंडिस

1
बहुत अच्छा और +1, लेकिन document.getElementByIdHTML जोड़ने के तुरंत बाद इसका उपयोग करना महंगा और अनावश्यक लगता है । यदि आप सैकड़ों तत्वों को जोड़ रहे हैं, तो यह बहुत अधिक ट्रैवर्सिंग कार्य है।
गॉर्जेल

@ggorlen I थोड़े रुचि से बाहर के सही क्षेत्र पर सहमत कक्षा का उपयोग कर nameरहा है और तत्व के माध्यम से गुजरते समय उस वर्ग को घटना को आकर्षित कर रहा है (या शायद घटना से केवल पढ़ने के लिए) अधिक कुशल हो सकता है?
पोग्रिंडिस

1
निश्चित नहीं। वास्तविक उपयोग पर निर्भर करता है - मेरा सुझाव समय से पहले अनुकूलन हो सकता है। आपको प्रोफ़ाइल / बेंचमार्क और देखना होगा। लेकिन अगर document.createElementइस्तेमाल किया जा सकता है, मुझे लगता है कि यह आमतौर पर सबसे अच्छा आधारभूत दृष्टिकोण है। इस पद के लिए एक और संभावित सुधार दो छोरों का उपयोग करना है: एक सभी एचटीएमएल का निर्माण करने के लिए, फिर एक document.querySelectorAllकॉल में एक वर्ग का उपयोग करके सभी तत्वों को हथियाने के लिए और एक घटना श्रोताओं को जोड़ने के लिए।
गगॉलेन

1
निश्चित रूप से एक बेंचमार्क के लायक, मैं आज रात करने के लिए कुछ भी बेहतर नहीं सोच सकता! :)
पोग्रिंडिस

8

का उपयोग +=पर innerHTMLHTML के अंदर तत्वों पर नष्ट कर देता है घटना श्रोताओं। ऐसा करने का सही तरीका उपयोग करना है document.createElement। यहाँ एक न्यूनतम, पूर्ण उदाहरण है:

for (let i = 1; i < 10; i++) {
  const anchor = document.createElement("a");
  document.body.appendChild(anchor);
  anchor.id = "title" + i;
  anchor.href= "#";
  anchor.textContent = "link " + i;
  document.getElementById("title" + i)
    .addEventListener("click", e => console.log(i));
}
a {
  margin-left: 0.3em;
}

बेशक, document.getElementByIdयहाँ आवश्यक नहीं है क्योंकि हमने लूप ब्लॉक में ऑब्जेक्ट बनाया है। इससे संभावित महंगे पेड़ चलते हैं।

for (let i = 1; i < 10; i++) {
  const anchor = document.createElement("a");
  document.body.appendChild(anchor);    
  anchor.href= "#";
  anchor.textContent = "link " + i;
  anchor.addEventListener("click", e => console.log(i));
}
a {
  margin-left: 0.3em;
}

यदि आपके पास अपने उदाहरण के रूप में कड़े HTML के मनमाने ढंग से विराम हैं, तो आप इसका उपयोग एक बार चंक पर createElement("div")सेट कर सकते हैं innerHTMLऔर श्रोताओं को आवश्यकतानुसार जोड़ सकते हैं। फिर divs को अपने कंटेनर तत्व के बच्चों के रूप में जोड़ें।

for (let i = 1; i < 10; i++) {
  const rawHTML = `<div><a href="#" id="link-${i}">link ${i}</a></div>`;
  const div = document.createElement("div");
  document.body.appendChild(div);
  div.href= "#";
  div.innerHTML = rawHTML;
  div.querySelector(`#link-${i}`)
    .addEventListener("click", e => console.log(i));
}


1
यह वह दृष्टिकोण है जिस पर मैं विचार कर रहा था, और मैं इसका हल दूंगा, लेकिन दूसरा उत्तर भी बहुत अच्छा है।
पोग्रिंडिस

डे उत्तर के लिए धन्यवाद, लेकिन मैंने createElement के साथ लेआउट बनाने की कोशिश की और मैं असफल रहा
लुइज़ एडोर्नो

1
कोई दिक्कत नहीं है। उम्मीद है कि आपको एहसास होगा कि अगर आपके पास HTML का एक बड़ा हिस्सा है, तो आप एक रूट तत्व कंटेनर बना सकते हैं जैसे कि <div>, फिर div.innerHTML += yourHugeChunkOfHTML। तो कोई कारण नहीं है कि यह किसी भी उपयोग के मामले के लिए काम नहीं करना चाहिए।
गगॉलेन

1
मैं आपकी सिफारिश के साथ इस लेआउट को बनाने की कोशिश करूंगा, मुझे कई बार "document.getElementById" का उपयोग करने से डर लगता है और प्रदर्शन को धीमा कर देता है
लुइज़ एडोर्नो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.