2009-02-27 12 views
64

निम्नलिखित उदाहरण कोड में, मैं onclick ईवेंट हैंडलर को "foo" टेक्स्ट वाले स्पैन में संलग्न करता हूं। हैंडलर एक अनाम कार्य है जो एक चेतावनी() को पॉप करता है।क्या वंश के कार्यक्रम श्रोताओं को नष्ट किए बिना आंतरिक HTML में जोड़ना संभव है?

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

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

<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> 
+0

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

उत्तर

88

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

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

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

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

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); 
    } 
} 
+0

क्या कोई ऐसा विकल्प है जो HTML के मनमानी ब्लॉब को जोड़ सकता है? – mike

+43

newcontent = document.createElement ('div'); newcontent.innerHTML = arbitrary_blob; जबकि (newcontent.firstChild) mydiv.appendChild (newcontent.firstChild); – bobince

+0

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

1

ईवेंट हैंडलर्स हार है, IMO, रास्ते में एक बग जावास्क्रिप्ट डोम संभालती है।

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

मैं इसे एक बग नहीं मानता। एक तत्व को बदलने का मतलब है कि आप इसे पूरी तरह से बदल दें। इससे पहले जो वहां था वह उत्तराधिकारी नहीं होना चाहिए। –

+0

लेकिन मैं किसी तत्व को प्रतिस्थापित नहीं करना चाहता; मैं सिर्फ माता-पिता को नए जोड़ना चाहता हूं। – mike

+0

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

3

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

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

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

-3

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

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

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

+0

है, यह उल्लसित है कि इस पूरी तरह गलत जवाब में अतिरिक्त टाइपिंग से परहेज करने के बारे में बताता है औचित्य, लगभग आधा कोड अनावश्यक है। – JLRishe

4

अब, और jQuery संलग्न करें और आगे जोड़ते कार्यों कि वास्तव में ऐसा करते हैं, वर्तमान सामग्री प्रभावशाली बिना सामग्री जोड़ दिया गया है: यहाँ कैसे मैं "foo" बदले बिना "बार" जोड़ना होगा है। बहुत उपयोगी।

+4

['.insertAdjacentHTML'] (https://developer.mozilla.org/en/DOM/element.insertAdjacentHTML) IE4 – Esailija

+1

@Esailija के बाद से रहा है, जो फ़ायरफ़ॉक्स में काम नहीं करता है। – Tynach

+0

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

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); 
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; 
    } 
} 
17

का उपयोग .insertAdjacentHTML() को बरकरार रखता है घटना श्रोताओं, और is supported by all major browsers। यह .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 --> 
+0

बहुत रोचक! इस समाधान के लिए धन्यवाद :) –

+0

सबसे सुगम समाधान, आईएमओ – Velojet

संबंधित मुद्दे