是否可以在不破坏后代事件监听器的情况下附加到innerHTML?
-
09-09-2019 - |
题
在下面的示例代码中,我附加了一个 onclick
包含文本“foo”的跨度的事件处理程序。该处理程序是一个匿名函数,它会弹出一个 alert()
.
但是,如果我分配给父节点的 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>
解决方案
不幸的是,分配给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);
}
}
其他提示
使用.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 -->
现在,它是2012年,和jQuery有追加和前置一个做的正是这种功能,添加内容,而不会影响当前的内容。非常有用的。
顺便说一句,如果您使用 jquery (v1.3) 等 javascript 库来进行 dom 操作,您可以利用实时事件来设置处理程序,例如:
$("#myspan").live("click", function(){
alert('hi');
});
并且它会在任何类型的 jquery 操作期间始终应用于该选择器。对于现场活动,请参阅: docs.jquery.com/events/live 对于 jquery 操作,请参阅: docs.jquery.com/manipulation
我创造了我的标记插入作为一个字符串,因为它是更少的代码,更容易比花哨的东西DOM工作阅读。
然后我做了一个临时的元素的innerHTML的只是让我可以把该元素的唯一孩子,重视身体。
var html = '<div>';
html += 'Hello div!';
html += '</div>';
var tempElement = document.createElement('div');
tempElement.innerHTML = html;
document.getElementsByTagName('body')[0].appendChild(tempElement.firstChild);
something.innerHTML + = '添加任何你想要';
它为我工作。我添加一个按钮来输入文本使用该溶液
有另外一种选择:使用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>
丢失的事件处理程序是,IMO,在方式的Javascript中的错误处理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;
}
}
的最简单的方法是使用一个数组并推动元件到它,然后插入阵列后续值到阵列动态。 这是我的代码:
var namesArray = [];
function myclick(){
var readhere = prompt ("Insert value");
namesArray.push(readhere);
document.getElementById('demo').innerHTML= namesArray;
}
是的,它是可能的,如果你直接绑定使用参数onclick="sayHi()"
类似像你<body onload="start()">
模板的事件 - 这种方法类似于框架角/ VUE /反应/等。您也可以使用 <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>
有关与报头和data.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>
我是懒惰的程序员。因为它似乎是多余的打字我不使用DOM。对我来说,更少的代码就更好了。以下是我想补充“巴”无需更换“富”:
function start(){
var innermyspan = document.getElementById("myspan").innerHTML;
document.getElementById("myspan").innerHTML=innermyspan+"bar";
}