I try to run the code it works for the first time but in the second time it won’t work I don’t know why ? I want to make it in a way that I can send several messages over and over
var message = document.querySelector('.container'); var btn = document.getElementById('btn'); var inpt = document.getElementById('txt'); function AddMessage() { if (String(inpt.value) != '' && isNaN(inpt.value) == true) { message.innerHTML += `<p>${inpt.value} </p>`; inpt.value = ''; } }
input { outline: none; }
<div class="container"> <input type="text" value="" id="txt"> <button id="btn" onclick="AddMessage()">send</button> <p>whats your name ?</p> </div>
Advertisement
Answer
Issues with .innerHTML
You are assigning to .innerHTML
. This causes recreation of the element’s descendants (see innerHTML
“On setting…”):
const oldReference = document.getElementById("element"); document.body.innerHTML += ""; // Assigning to innerHTML const newReference = document.getElementById("element"); const isSameElement = oldReference === newReference; console.log({ isSameElement });
<div id="element">
As you can see, the old references btn
and inpt
won’t be the elements currently in the DOM.
Sidenote: Parsing .innerHTML
may be quite time-consuming, and its use with user input is a security issue.
Security considerations
Especially with user input you shouldn’t use .innerHTML
, because that is an easy way to insert scripts into your webpage:
document.body.addEventListener("click", evt => { if (!evt.target.closest("button")) return; const input = document.querySelector("input"); document.body.innerHTML += input.value; });
pre{padding:2px 4px;border:1px solid;width:min-content}
<input><button>Insert</button> <p>Try to input this:</p> <pre><code><img src="" onerror="console.log('any script here!')"></code></pre> <p>Then look into your browser console.
Alternatives for .innerHTML
If you want to add elements, you can use document.createElement()
, Element.append()
, and Node.textContent
:
const input = document.querySelector("input"); document.querySelector("button").addEventListener("click", evt => { const p = document.createElement("p"); p.textContent = input.value; document.body.append(p); input.value = ""; const currentInput = document.querySelector("input"); console.log("Is same input?", input === currentInput); });
<input><button>Insert</button> <p>Also try adding some HTML, for example: <code><span>Test</span>