Tzar
Tzar

Reputation: 4789

Problem with addEventListener("load") when used with <iframe> in Firefox

I have an iframe that is a target for a form. The iframe should remove the main element when submit is pressed. This works as expected in all major browsers except Firefox, where main is removed immediately on page load.

Is this just a bug in Firefox, or am I missing something?


document.addEventListener("DOMContentLoaded", _ => {
  
  // Create an iframe and submit a form to it
  // ========================================

  const form = document.forms[0]
  form.setAttribute("target", "Response")

  const iframe = Object.assign(document.createElement("iframe"), {
    name: "Response"
  })
  iframe.hidden = true
  document.body.appendChild(iframe)

  iframe.addEventListener("load", () => {
    const main = document.querySelector("body > main")

    main.remove()

    iframe.hidden = false
  })
})
<main>
  <form action=https://script.google.com/macros/s/AKfycbzz-KveHder1A3CX8GcqZI6GR2MQj66PDRWNKoatIET_LXNqQs/exec method=get>
    <fieldset>
      <legend>Foobar</legend>
      <label><input type=radio name=Foobar value=Foo>Foo</label><br>
      <label><input type=radio name=Foobar value=Bar>Bar</label><hr>
      <input type=submit value=Submit>
    </fieldset>
  </form>
</main>

Upvotes: 3

Views: 456

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074495

Sounds like Firefox is triggering load when the blank iframe loads and the others aren't.

A couple of approaches come to mind for addressing that:

  • You could check the location of the iframe to make sure it's what you're expecting

  • You could set the load handler only after you see a submit event on the form. The submit event will definitely be before the load related to it, because submit happens before form submission.

To me, the second way seems like the way to go.


Re using location, in rough terms (see comments):

iframe.addEventListener("load", () => {
  // *** Only process the event if the iframe's location is the expected origin
  if (String(iframe.contentWindow.location).startsWith("https://script.google.com")) {
    const main = document.querySelector("body > main")

    main.remove()

    iframe.hidden = false
  }
})

(startsWith is a bit newish, but easily polyfilled if necessary.)

Upvotes: 2

Related Questions