DEV Community

Kenji Tomita
Kenji Tomita

Posted on

Implementing Exit Popups with beforeunload and history.pushState

In web development, enhancing user experience is a pivotal aspect. One way to improve this experience is by preventing users from inadvertently leaving a page, especially when they are in the middle of entering important information. This article introduces how to use the beforeunload event and history.pushState method to display exit popups, along with a discussion on cross-browser behavior, including Safari's specific responses.

Utilizing the beforeunload Event

The beforeunload event triggers when a user attempts to leave a page (e.g., by clicking a link or changing the URL manually). Utilizing this event, we can prompt the user with a warning dialog, asking them to confirm their intention to leave the page. Below is a sample code snippet that demonstrates how to implement a standard warning dialog when the user tries to navigate away from a page containing a text input.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Sample</title>
</head>
<body>
  <script>
    document.addEventListener('DOMContentLoaded', function() {
      window.addEventListener('beforeunload', function(e) {
        // Display the default exit warning dialog
        e.preventDefault();
      });
    });
  </script>
  <div>
    <input type="text">
  </div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Leveraging history.pushState for Back Navigation

By combining the history.pushState method with the popstate event, you can customize the browser's back button behavior. The following sample showcases how to display a custom confirmation dialog when a user, having made changes to input fields, attempts to leave the page.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Sample</title>
</head>
<body>
  <script>
    const setupLeaveConfirmation = () => {
      history.pushState(null, '', location.href);

      window.addEventListener('popstate', function() {
        if (!hasInputChanged()) {
          // If no changes were made, allow leaving the page
          history.go(-1);
          return;
        }
        // If changes were made, show a confirmation dialog
        confirm('Leave this page?');
      });  
    }

    const hasInputChanged = () => {
      const inputs = document.querySelectorAll('input:not([type="hidden"])');
      return Array.from(inputs).some(input => input.value.trim() !== '');
    }

    document.addEventListener('DOMContentLoaded', setupLeaveConfirmation);
  </script>
  <div>
    <input type="text" />
  </div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Cross Browser Behavior and Safari Considerations

When utilizing these techniques, it's important to be mindful of different browser behaviors. Specifically, in Safari, the beforeunload event may not support custom message displays, and the behavior of history.pushState and popstate events can differ from other browsers. Developers are encouraged to conduct thorough cross-browser testing to ensure a consistent experience for all users.

Conclusion

Using the beforeunload event and history. pushState method to implement exit popups is an effective way to prevent users from accidentally losing information by leaving a page prematurely However, understanding the differences in browser behavior, particularly for Safari, and conducting appropriate testing, is crucial in providing a consistent user experience across all browsers.

Top comments (0)