HTML:
<h1 id="ws-title"></h1>
<time datetime="" id="ws-date"></time>
JS:
inp1 = document.querySelector("input[name='ws-date']");
out1 = document.querySelector("#ws-date");
inp1.addEventListener("input", e => {
out1.textContent=e.target.value;
});
inp2 = document.querySelector("input[name='ws-title']");
out2 = document.querySelector("#ws-title");
inp2.addEventListener("input", e => {
out2.textContent=e.target.value;
});
Works as expected (i.e: changing input changes corresponsing h2).
However:
function pairListen(name) {
inp = document.querySelector(`input[name='${name}']`);
out = document.querySelector(`#${name}`);
inp.addEventListener("input", e => {
out.textContent=e.target.value;
});
}
pairListen("ws-title");
pairListen("ws-date");
Causes <h2 id="ws-date"> to be changed when <input name="ws-title"> is changed and vice versa.
Why is that? All difference is that repeated code is embedded in a function.
That's because when you declare a variable without a declarator (i.e. var, let, or const) it automatically gets defined in window, this, and globalThis (making those kinds of variables global, accessible anywhere in your code). The second time you do varName = "value";, you're not redeclaring the variable. You're modifying it. You can solve this by applying a declarator.
function pairListen(name) {
const inp = document.querySelector(`input[name='${name}']`);
const out = document.querySelector(`#${name}`);
inp.addEventListener("input", e => {
out.textContent=e.target.value;
});
}
pairListen("ws-title");
pairListen("ws-date");
<h1 id="ws-title"></h1>
<input name="ws-title" />
<h2 id="ws-date"></h2>
<input name="ws-date" />
Moral of the story—always declare variables with declarators, or you'll encounter unprecedented results. You can force yourself to follow good style by adding "use strict"; to the top of all your JavaScript files, which will not tolerate writing code that will give you unexpected results.