それは子孫イベントリスナーを破壊することなく、innerHTMLプロパティに追加することは可能ですか?
-
09-09-2019 - |
質問
次のコード例では、私は、テキスト「foo」を含むスパンにonclick
イベントハンドラを添付してください。ハンドラが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
ためのシンプルな1行の交換です。
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のは、現在のコンテンツに影響を与えることなく、コンテンツを追加、まさにこれを行う機能を追加し、先頭に追加持っています。非常に便利です。
は、わずかな(しかし関連)assideとして、あなたがライブイベントを利用することができます:
$("#myspan").live("click", function(){
alert('hi');
});
、それはjQueryの操作の任意の種類の中に常にそのセレクタに適用されます。ライブイベントでは次を参照してください。 docs.jquery.com/events/live のjqueryの操作のためには、以下を参照してください< href = "http://docs.jquery.com/Manipulation" のrel = "nofollowをnoreferrer"> 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()">
を使用してイベントをバインドする場合は、はい、それは可能です。また、ダイナミック」を操作するために <template>
を使用することができますここの LIKE '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を使用しないでください。私には、以下のコードでは、より良いです。ここで私は「foo」を交換することなく、「バー」を追加する方法は次のとおりです。
function start(){
var innermyspan = document.getElementById("myspan").innerHTML;
document.getElementById("myspan").innerHTML=innermyspan+"bar";
}