Why is it that a write()
function called through an onclick attribute resolves to document.write()
and replaces the document? Is there any way to stop this from happening?
<!-- Replaces the document with the text "from onclick." -->
<button onclick="write('from onclick.')">Write Function</button>
<!-- Logs the text "Alternate write function triggered... from onclick." -->
<button onclick="altWrite('from onclick.')">Alternate Write Function</button>
<script>
function write (arg) {
console.log("Write function triggered... " + arg);
}
function altWrite (arg) {
console.log("Alternate write function triggered... " + arg);
}
// Logs the text "Write function triggered... from code."
write("from code.");
// Logs the text "Alternate write function triggered... from code."
altWrite("from code.");
</script>
Inline handlers unfortunately have unintuitive with
blocks for:
(1) the element that they're called on (here, the button)
(2) the document:
So, when write
is called from the inline handler, the scope chain first sees the write
property on document
(and calls it as a result), instead of continuing on to search for the write
property on window
(which is where the write function you defined exists).
The solution is to not use an inline handler: use addEventListener
instead.
function write(arg) {
console.log("Write function triggered... " + arg);
}
function altWrite(arg) {
console.log("Alternate write function triggered... " + arg);
}
const [button1, button2] = document.querySelectorAll('button');
button1.addEventListener('click', write);
button2.addEventListener('click', altWrite);
<button>Write Function</button>
<button>Alternate Write Function</button>