是否有可能附加到innerHTML而不破坏后代的事件侦听器?
在下面的示例代码中,我将一个onclick
事件处理程序附加到包含文本“foo”的跨度。 处理程序是一个匿名函数,popupalert()。
但是,如果我分配给父节点的innerHTML
,这个onclick
事件处理程序被破坏 – 单击“foo”将无法popup警告框。
这是可以修复的吗?
<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>
不幸的是,赋值给innerHTML
会导致所有子元素的破坏,即使你试图追加。 如果您想保留子节点(及其事件处理程序),则需要使用DOMfunction :
function start() { var myspan = document.getElementById("myspan"); myspan.onclick = function() { alert ("hi"); }; var mydiv = document.getElementById("mydiv"); mydiv.appendChild(document.createTextNode("bar")); }
编辑:鲍勃的解决scheme,从评论。 发表你的答案,鲍勃! 获得信贷。 🙂
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); } }
使用.insertAdjacentHTML()
保留事件监听器,并受所有主stream浏览器的支持 。 这是.innerHTML
的一个简单的单行replace。
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 -->
现在是2012年了,jQuery有追加和前置function,可以做到这一点,添加内容而不影响当前的内容。 很有用。
作为一个轻微的(但相关的)的帮助,如果你使用jQuery(v1.3)这样的javascript库来做你的dom操作,你可以利用实时事件来设置一个处理程序,如:
$("#myspan").live("click", function(){ alert('hi'); });
并且在任何types的jQuery操作过程中都会被应用到该select器。 有关直播活动,请参阅: docs.jquery.com/events/live for jquery manipulation请参阅: docs.jquery.com/manipulation
我创build了我的标记插入作为一个string,因为它比较less的代码,更容易阅读比花哨的东西。
然后,我把它作为临时元素的内在,以便我可以把这个元素的独一无二的孩子带到身体上。
var html = '<div>'; html += 'Hello div!'; html += '</div>'; var tempElement = document.createElement('div'); tempElement.innerHTML = html; document.getElementsByTagName('body')[0].appendChild(tempElement.firstChild);
失去事件处理程序是,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 }
你可以这样做:
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; } }
我是一个懒惰的程序员。 我不使用DOM,因为它看起来像额外的打字。 对我来说,代码越less越好。 这里是我将如何添加“酒吧”而不更换“富”:
function start(){ var innermyspan = document.getElementById("myspan").innerHTML; document.getElementById("myspan").innerHTML=innermyspan+"bar"; }