Building an Exit Popup with JavaScript
Tags: javascript, tutorial, webdev, frontend
Published: 2019-06-08 01:01:47

---
title: Building an Exit Popup with JavaScript
published: true
description: Learn how to build a popup that captures exit intent with a few lines of JavaScript
cover_image: https://thepracticaldev.s3.amazonaws.com/i/0vh4p6qtbzbmn3qjqrko.png
tags: javascript, tutorial, webdev, frontend
---

I recently built a system that shows a popup to users when they are about to exit a site. I thought I would share my approach and a couple of tricks I've learned along the way. I'm going to stick with vanilla JavaScript to make this as approachable as possible.

> Disclaimer: exit popups can annoy users, so I recommend using them in moderation!

# Markup and styling

Let's write some markup for our popup:

```html
<div id="popup" class="popup__wrapper">
  <div class="popup__container">
    <h1 class="popup__title">Thank you for visiting!</h1>
    <p>Have a wonderful day 💁</p>
  </div>
</div>
```

The `popup__wrapper` is a transparent overlay that goes over the page. The `popup__container` will wrap the content we'd like to display.

Here's the CSS I used:

```css
* {
  box-sizing: border-box;
}

#popup {
  display: none;
}

.popup__wrapper {
  background: rgba(0, 0, 0, .75);
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  z-index: 10;
}

.popup__container {
  background: #fff;
  font-family: Helvetica, Arial, sans-serif;
  font-size: 18px;
  margin: 100px auto;
  max-width: 100%;
  padding: 20px;
  width: 500px;
}

.popup__title {
  font-size: 26px;
  margin-bottom: 15px;
}
```

The most important bit is the `display: none` on the `#popup` selector: this hides the content until we want to show it.

## Adding functionality

Let's now write a few lines of JavaScript to show the popup when the mouse leaves the window:

```js
function onMouseOut(event) {
  // Remove this event listener
  document.removeEventListener("mouseout", onMouseOut);
  
  // Show the popup
  document.getElementById("popup").style.display = "block";
}

document.addEventListener("mouseout", onMouseOut);
```

The popup should now show up when your mouse leaves the window!

Here's a CodePen for reference:

{% codepen https://codepen.io/deammer/pen/GaVqRM %}

# Refining the system

When users want to leave a site, they usually move their mouse to the URL bar or the Back button at the top of their browser. To make popups a little less eager, we could use that to our advantage:

```javascript
function onMouseOut(event) {
  // If the mouse is near the top of the window, show the popup
  if (event.clientY < 50) {
    // Remove this event listener
    document.removeEventListener("mouseout", onMouseOut);
  
    // Show the popup
    document.getElementById("popup").style.display = "block";
  }
}

document.addEventListener("mouseout", onMouseOut);
```

# Fixing a Firefox bug

I noticed that the popup shows up when clicking or hovering on a `<select>` element in Firefox. 

You can test this by adding a dropdown to the DOM and clicking on it in Firefox:

```html
<div id="popup" class="popup__wrapper">
  <div class="popup__container">
    <h1 class="popup__title">Thank you for visiting!</h1>
    <p>Have a wonderful day 💁</p>
  </div>
</div>

<select>
  <option>Oh</option>
  <option>No</option>
</select>
```

This is very annoying!

After a few hours of iterations, I came to a solution:

```javascript
function onMouseOut(event) {
  // If the mouse is near the top of the window, show the popup
  // Also, do NOT trigger when hovering or clicking on selects
  if (
    event.clientY < 50 &&
    event.relatedTarget == null &&
    event.target.nodeName.toLowerCase() !== 'select') {
    // Remove this event listener
    document.removeEventListener("mouseout", onMouseOut);
  
    // Show the popup
    document.getElementById("popup").style.display = "block";
  }
}

document.addEventListener("mouseout", onMouseOut);
```

The popup now works as expected in Firefox! Here's another CodePen with the improvements:

{% codepen https://codepen.io/deammer/pen/EzqyEg %}


---

I hope this post was informative! Please let me know what you think in the comments below, and happy coding!