Search code examples
javascripthtmlonclickdocument.write

Why does a function write() called from an onclick attribute resolve to document.write()?


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>

Solution

  • Inline handlers unfortunately have unintuitive with blocks for:

    (1) the element that they're called on (here, the button)

    (2) the document:

    enter image description here

    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>