하위 항목의 이벤트 리스너를 파괴하지 않고 innerHTML에 추가할 수 있습니까?

StackOverflow https://stackoverflow.com/questions/595808

문제

다음 예제 코드에서는 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";
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top