क्या वंश के घटना श्रोताओं को नष्ट किए बिना इनर HTML में जोड़ना संभव है?


112

निम्नलिखित उदाहरण कोड में, मैं एक onclickघटना हैंडलर को पाठ "फू" वाले स्पैन से जोड़ता हूं । हैंडलर एक अनाम फ़ंक्शन है जो एक पॉप अप करता हैalert()

हालाँकि, अगर मैं मूल नोड के लिए असाइन करता हूँ innerHTML, यहonclick ईवेंट हैंडलर नष्ट हो जाता है - "फू" पर क्लिक करने से अलर्ट बॉक्स पॉप अप करने में विफल रहता है।

क्या यह ठीक है?

<html>
 <head>
 <script type="text/javascript">

  function start () {
    myspan = document.getElementById("myspan");
    myspan.onclick = function() { alert ("hi"); };

    mydiv = document.getElementById("mydiv");
    mydiv.innerHTML += "bar";
  }

 </script>
 </head>

 <body onload="start()">
   <div id="mydiv" style="border: solid red 2px">
     <span id="myspan">foo</span>
   </div>
 </body>

</html>

यह प्रश्न 'नए फ़ील्ड को प्रपत्र में जोड़ने से उपयोगकर्ता इनपुट मिटाता है' समस्या से संबंधित है। चयनित उत्तर इन दोनों समस्याओं को बहुत अच्छी तरह से ठीक करता है।
मैट जूल

इस समस्या से निपटने के लिए इवेंट डेलिगेशन का इस्तेमाल किया जा सकता है।
dasfdsa

जवाबों:


126

दुर्भाग्य से, innerHTMLसभी बाल तत्वों के विनाश का कारण बनता है, भले ही आप संलग्न करने की कोशिश कर रहे हों। यदि आप चाइल्ड नोड्स (और उनके ईवेंट हैंडलर) को संरक्षित करना चाहते हैं, तो आपको DOM फ़ंक्शंस का उपयोग करना होगा :

function start() {
    var myspan = document.getElementById("myspan");
    myspan.onclick = function() { alert ("hi"); };

    var mydiv = document.getElementById("mydiv");
    mydiv.appendChild(document.createTextNode("bar"));
}

संपादित करें: टिप्पणियों से बॉब का समाधान। अपना जवाब पोस्ट करें, Bob! इसका श्रेय प्राप्त करें। :-)

function start() {
    var myspan = document.getElementById("myspan");
    myspan.onclick = function() { alert ("hi"); };

    var mydiv = document.getElementById("mydiv");
    var newcontent = document.createElement('div');
    newcontent.innerHTML = "bar";

    while (newcontent.firstChild) {
        mydiv.appendChild(newcontent.firstChild);
    }
}

क्या कोई विकल्प है जो HTML की मनमानी बूँद को जोड़ सकता है?
माइक

64
newcontent = document.createElement ('div'); newcontent.innerHTML = मनमाना_blob; जबकि (newcontent.firstChild) mydiv.appendChild (newcontent.firstChild);
बोबिन्स

अच्छा लगा, बॉब! यदि आप एक अच्छी तरह से प्रारूपित उत्तर के रूप में पोस्ट करते हैं, तो मैं इसे चुनूँगा।
माइक

@bobince - मैंने अपनी तकनीक के साथ अपना जवाब अपडेट किया है, क्योंकि आपने इसे अभी तक खुद पोस्ट नहीं किया है। यदि आप अपना स्वयं का उत्तर बनाते हैं, तो आगे बढ़ें और मुझे वापस रोल करें। :-)
बेन ब्लैंक

2
ओह, एक आखिरी बात, आप गलती से फैलने वाले ग्लोब से बचने के लिए "var myspan", "var newcontent" आदि चाहते हैं।
बोबिन्स

85

का उपयोग करते हुए .insertAdjacentHTML()बरकरार रखता घटना श्रोताओं, और सभी प्रमुख ब्राउज़रों द्वारा समर्थित है । यह एक सरल एक-पंक्ति प्रतिस्थापन है .innerHTML

var html_to_insert = "<p>New paragraph</p>";

// with .innerHTML, destroys event listeners
document.getElementById('mydiv').innerHTML += html_to_insert;

// with .insertAdjacentHTML, preserves event listeners
document.getElementById('mydiv').insertAdjacentHTML('beforeend', html_to_insert);

'beforeend'जहां तत्व में तर्क निर्दिष्ट HTML सामग्री डालने के लिए। विकल्प हैं 'beforebegin', 'afterbegin', 'beforeend', और 'afterend'। उनके संबंधित स्थान हैं:

<!-- beforebegin -->
<div id="mydiv">
  <!-- afterbegin -->
  <p>Existing content in #mydiv</p>
  <!-- beforeend -->
</div>
<!-- afterend -->

आपने मेरा दिन बचाया!
तुरल असगर

सबसे अच्छा उपाय। धन्यवाद!
दाऊदजी

3

अब, यह 2012 है, और jQuery में एपेंड और प्रीपेन्ड फ़ंक्शन हैं जो वास्तव में ऐसा करते हैं, वर्तमान सामग्री को प्रभावित किए बिना सामग्री जोड़ते हैं। बहुत उपयोगी।


7
.insertAdjacentHTMLIE4 के बाद से चारों ओर रहा है
Esailija

1
@Tynach हाँ यह करता है, यह उनकी जावास्क्रिप्ट साइट है जो इसे सबसे अच्छा दस्तावेज बनाती है: developer.mozilla.org/en-US/docs/Web/API/Element/…
जॉर्डन बैडवेल

2
@ जोर्डनबेडवेल, मुझे ईमानदारी से पता नहीं है कि मैंने पहले क्यों कहा। आप 100% सही हैं। मुझे लगता है कि जिस समय मैंने संक्षेप में इसे देखा था और इसे नहीं पा सका था, लेकिन ... ईमानदारी से कहूं तो मेरे पास कोई बहाना नहीं है। एस्लिजा भी उस पेज से जुड़ता है।
टिंच सिप

ओपी jQuery के बारे में बात नहीं कर रहा है
आंद्रे मार्कोंडेस टेक्सेरा

2

एक मामूली (लेकिन संबंधित) के रूप में, यदि आप एक जावास्क्रिप्ट लाइब्रेरी का उपयोग करते हैं जैसे कि jquery (v1.3) अपना डोम हेरफेर करने के लिए आप लाइव इवेंट का उपयोग कर सकते हैं जिससे आप एक हैंडलर सेट करते हैं जैसे:

 $("#myspan").live("click", function(){
  alert('hi');
});

और यह किसी भी तरह के जॉकरी हेरफेर के दौरान हर समय उस चयनकर्ता पर लागू होगा। लाइव इवेंट के लिए देखें: jocsery हेरफेर के लिए docs.jquery.com/events/live देखें: docs.jquery.com/manipulation


1
ओपी jQuery के बारे में बात नहीं कर रहा है
André Marcondes Teixeira

2

मैंने अपने मार्कअप को एक स्ट्रिंग के रूप में सम्मिलित करने के लिए बनाया क्योंकि यह कम कोड है और फैंसी डोम सामग्री के साथ काम करने से पढ़ने में आसान है।

फिर मैंने इसे एक अस्थायी तत्व का आंतरिक HTML बना दिया ताकि मैं उस तत्व के एक और एकमात्र बच्चे को ले जा सकूं और शरीर को संलग्न कर सकूं।

var html = '<div>';
html += 'Hello div!';
html += '</div>';

var tempElement = document.createElement('div');
tempElement.innerHTML = html;
document.getElementsByTagName('body')[0].appendChild(tempElement.firstChild);

2

कुछ.innerHTML + = 'जो आप चाहते हैं उसे जोड़ें';

यह मेरे लिए काम किया। मैंने इस समाधान का उपयोग करते हुए एक इनपुट पाठ में एक बटन जोड़ा


यह सबसे सरल तरीका है, जो आपको धन्यवाद देता है!
डेमो 7up

4
यह सभी घटनाओं को नष्ट कर देता है।
असगर

1
यह वास्तव में समाधान कैसे है? यह सभी घटनाओं को नष्ट कर देता है !!
डेनिश

1

एक और विकल्प है: setAttributeईवेंट श्रोता को जोड़ने के बजाय उपयोग करना । ऐशे ही:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Demo innerHTML and event listeners</title>
<style>
    div {
        border: 1px solid black;
        padding: 10px;
    }
</style>
</head>
<body>
    <div>
        <span>Click here.</span>
    </div>
    <script>
        document.querySelector('span').setAttribute("onclick","alert('Hi.')");
        document.querySelector('div').innerHTML += ' Added text.';
    </script>
</body>
</html>


1

हां यह संभव है यदि आप onclick="sayHi()"अपने जैसे टेम्पलेट में सीधे टैग विशेषता का उपयोग करके घटनाओं को बांधते हैं <body onload="start()">- यह दृष्टिकोण चौखटे के समान है। आप यहां<template> 'डायनामिक' html पर काम करने के लिए भी उपयोग कर सकते हैं । यह सख्त विनीत js नहीं है, हालांकि यह छोटी परियोजनाओं के लिए स्वीकार्य है

function start() {
  mydiv.innerHTML += "bar";
}

function sayHi() {
  alert("hi");
}
<body onload="start()">
  <div id="mydiv" style="border: solid red 2px">
    <span id="myspan" onclick="sayHi()">foo</span>
  </div>
</body>


0

हारने वाले इवेंट हैंडलर, IMO, जावास्क्रिप्ट को DOM हैंडल करने के तरीके में एक बग है। इस व्यवहार से बचने के लिए, आप निम्नलिखित जोड़ सकते हैं:

function start () {
  myspan = document.getElementById("myspan");
  myspan.onclick = function() { alert ("hi"); };

  mydiv = document.getElementById("mydiv");
  clickHandler = mydiv.onclick;  // add
  mydiv.innerHTML += "bar";
  mydiv.onclick = clickHandler;  // add
}

2
मैं इसे बग नहीं मानता। किसी तत्व को बदलने का मतलब है कि आप इसे पूरी तरह से बदल देंगे। इससे पहले जो होना चाहिए था, उसे विरासत में नहीं मिलना चाहिए।
डायोडस - जेम्स मैकफर्लेन

लेकिन मैं एक तत्व को बदलना नहीं चाहता; मैं सिर्फ नए लोगों को अभिभावक के साथ जोड़ना चाहता हूं।
माइक

यदि आप तत्व की जगह ले रहे हैं, तो मैं सहमत हूँ, @ डायोडस। यह .innerHTML नहीं है जिसमें इवेंट हैंडलर है, लेकिन .innerHtml का जनक है।
हाँ - वह जेक।

2
जब इसके भीतर की HTML सामग्री बदली जाती है, तो आंतरिक HTML का स्वामी हैंडलर नहीं खोता है। और जावास्क्रिप्ट को पता नहीं है कि आप केवल नए बच्चों को जोड़ रहे हैं, क्योंकि "x.innerHTML + = y" स्ट्रिंग ऑपरेशन "x.innerHTML = x.innerHTML + y" के लिए केवल वाक्य रचना चीनी है।
बोबिन्स

आपको पुनः संलग्न करने की आवश्यकता नहीं है mydiv.onclick। केवल आंतरिक स्पैन की ऑन्क्लिक द्वारा ओवरराइड की जाती है innerHTML +=
वर्धमान ताजा

0

आप इसे इस तरह से कर सकते हैं:

var anchors = document.getElementsByTagName('a'); 
var index_a = 0;
var uls = document.getElementsByTagName('UL'); 
window.onload=function()          {alert(anchors.length);};
for(var i=0 ; i<uls.length;  i++)
{
    lis = uls[i].getElementsByTagName('LI');
    for(var j=0 ;j<lis.length;j++)
    {
        var first = lis[j].innerHTML; 
        string = "<img src=\"http://g.etfv.co/" +  anchors[index_a++] + 
            "\"  width=\"32\" 
        height=\"32\" />   " + first;
        lis[j].innerHTML = string;
    }
}

0

सबसे आसान तरीका एक सरणी का उपयोग करना है और इसमें तत्वों को धक्का देना है और फिर सरणी में बाद के मानों को गतिशील रूप से डालें। यहाँ मेरा कोड है:

var namesArray = [];

function myclick(){
    var readhere = prompt ("Insert value");
    namesArray.push(readhere);
    document.getElementById('demo').innerHTML= namesArray;
}

0

हेडर और डेटा के साथ किसी भी ऑब्जेक्ट ऐरे के लिए।jsfiddle

https://jsfiddle.net/AmrendraKumar/9ac75Lg0/2/

<table id="myTable" border='1|1'></table>

<script>
  const userObjectArray = [{
    name: "Ajay",
    age: 27,
    height: 5.10,
    address: "Bangalore"
  }, {
    name: "Vijay",
    age: 24,
    height: 5.10,
    address: "Bangalore"
  }, {
    name: "Dinesh",
    age: 27,
    height: 5.10,
    address: "Bangalore"
  }];
  const headers = Object.keys(userObjectArray[0]);
  var tr1 = document.createElement('tr');
  var htmlHeaderStr = '';
  for (let i = 0; i < headers.length; i++) {
    htmlHeaderStr += "<th>" + headers[i] + "</th>"
  }
  tr1.innerHTML = htmlHeaderStr;
  document.getElementById('myTable').appendChild(tr1);

  for (var j = 0; j < userObjectArray.length; j++) {
    var tr = document.createElement('tr');
    var htmlDataString = '';
    for (var k = 0; k < headers.length; k++) {
      htmlDataString += "<td>" + userObjectArray[j][headers[k]] + "</td>"
    }
    tr.innerHTML = htmlDataString;
    document.getElementById('myTable').appendChild(tr);
  }

</script>

-5

मैं एक आलसी प्रोग्रामर हूं। मैं DOM का उपयोग नहीं करता क्योंकि यह अतिरिक्त टाइपिंग की तरह लगता है। मेरे लिए, कम कोड बेहतर है। यहां बताया गया है कि मैं "फू" की जगह के बिना "बार" कैसे जोड़ूंगा:

function start(){
var innermyspan = document.getElementById("myspan").innerHTML;
document.getElementById("myspan").innerHTML=innermyspan+"bar";
}

15
यह प्रश्न पूछ रहा है कि इवेंट हैंडलर को खोए बिना ऐसा कैसे करें, इसलिए आपका उत्तर प्रासंगिक नहीं है, और btw यह वही है जो + = करता है, जो छोटा है
wlf

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