하위 항목의 이벤트 리스너를 파괴하지 않고 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"));
}
편집하다: 의견에서 밥의 해결책. 대답을 게시하십시오, 밥! 그것에 대한 신용을 얻으십시오. :-)
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는이 작업을 정확하게 수행하는 기능을 추가하고 Prepend 기능을 수행하여 현재 컨텐츠에 영향을 미치지 않으면 서 콘텐츠를 추가합니다. 매우 유용한.
약간의 (그러나 관련) Asside로서, jQuery (v1.3)와 같은 JavaScript 라이브러리를 사용하여 DOM 조작을 수행하는 경우 라이브 이벤트를 사용할 수있어 다음과 같은 핸들러를 설정할 수 있습니다.
$("#myspan").live("click", function(){
alert('hi');
});
그리고 그것은 모든 종류의 jQuery 조작 중에 항상 해당 선택기에 적용될 것입니다. 라이브 이벤트는 다음을 참조하십시오. docs.jquery.com/events/live jQuery 조작은 다음을 참조하십시오. docs.jquery.com/manipulation
Code가 적고 읽기가 더 쉽고 Fancy Dom과 함께 작업하는 것보다 문자열로 삽입하기 위해 마크 업을 만들었습니다.
그런 다음 임시 요소의 내부를 만들었으므로 그 요소의 유일한 아이를 가져 와서 몸에 부착 할 수있었습니다.
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()">
-이 접근법은 Frameworks Angular/Vue/React/etc와 유사합니다. 당신은 또한 사용할 수 있습니다 <template>
'Dynamic'HTML Like에서 작동합니다 여기. 그것은 엄격한 눈에 띄지 않는 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>
헤더 및 데이터가있는 객체 배열의 경우.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을 사용하지 않습니다. 나에게 코드가 적을수록 좋습니다. "foo"를 대체하지 않고 "bar"를 추가하는 방법은 다음과 같습니다.
function start(){
var innermyspan = document.getElementById("myspan").innerHTML;
document.getElementById("myspan").innerHTML=innermyspan+"bar";
}