Search code examples
javascriptiframebrowseraddeventlisteneronbeforeunload

How to remove beforeunload event listeners added by the iFrame?


How can I remove beforeunload event listeners added by the iFrame? My case is the iframe I load add some beforeunload events to the DOM, which I want to remove in case the session expires(or say for a particular event) and I don't want to show the confirmation message to the user. So is there any way I can remove event listeners from the iframe using javascript? Any help will be appreciated.

// parent.html

<!DOCTYPE html>
<html>
  <head>
    <title>Parent Frame</title>
    <script>
      window.addEventListener('beforeunload', function(event) {
        console.log('I am the 1st one.');
      });
      window.addEventListener('unload', function(event) {
        console.log('I am the 3rd one.');
      });
    </script>
  </head>
  <body>
    <iframe src="child-frame.html"></iframe>
  </body>
</html>

// child.html

<!DOCTYPE html>
<html>
  <head>
    <title>Child Frame</title>
    <script>
      window.addEventListener('beforeunload', function(event) {
        console.log('I am the 2nd one.');
      });
      window.addEventListener('unload', function(event) {
        console.log('I am the 4th and last one…');
      });
    </script>
  </head>
  <body>
      ☻
  </body>
</html>

Solution

  • I were able to reproduce this behavior only on chrome, FF doesn't seem to fire the event across iframes.

    One workaround I found (might not be the best), is to remove the iframe before leaving the page :

    mainWindow.onbeforeunload = e => { iframe.parentNode.removeChild(iframe) };
    

    This way, the event doesn't bubble to the iframe's window anymore.

    // toggle the blocking script
    inp.onchange = 
      e => window.onbeforeunload = inp.checked ?
        blockMessage :
        null;
    
    function blockMessage(e){
      iframe.parentNode.removeChild(iframe);
      }
    <h3>click "Run code snippet" again</h3>
    <label>block iframe's beforeunload<input type="checkbox" id="inp"></label><br>
    <iframe id="iframe" src="data:text/html,%3Chtml%3E%3Chead%3E%3Cscript%3Eonbeforeunload%20%3D%20e%20%3D%3E%20%22bye%22%3B%3C%2Fscript%3E%3C%2Fhead%3E%3C%2Fhtml%3E"></iframe>
    
    <!-- Decoded iframe content : 
      <html>
      <head>
      <script>
      	onbeforeunload = e => "bye";
      </script>
      </head>
      </html>
    -->