Creating a dismissible banner component with Vanilla JavaScript

Journal

Dismissible banner messages are a common element found in web applications & sites. This tutorial details how to create a simple re-usable component using Vanilla JavaScript.

Dismissible banner messages are a common element found in web applications & sites. This tutorial details how to create a simple re-usable component using Vanilla JavaScript.

Markup

<div
  data-component="dismissible-item"
  data-type="error"
  data-value="<strong>Error!</strong> Something went wrong. Please try again."
></div>

Let’s start with the HTML markup. A simple div element with three attributes. The data-component property is for our JavaScript to know that this should be used for a banner component. data-type enables a styling option for our banner (error, info, success or warning), and data-value is the copy we would like to display to our user.

Checking the DOM for banner components, and initialising them:

var dismissibles = Array.prototype.slice(
  document.querySelectorAll('[data-component="dismissible-item"]')
)
if (dismissibles.length) {
  for (var i = 0; i < dismissibles.length; i++) {
    var type = dismissibles[i].getAttribute('data-type'),
      value = dismissibles[i].getAttribute('data-value')
    new dismissibleItem(dismissibles[i], type, value)
  }
}

First, we create an array based on all elements in the document with the attribute data-component=”dismissible-item”.

After checking the array’s length to see if there are any elements, we loop through, selecting the data attributes, and initialise a new dismissibleItem for each.

new dismissibleItem(el, type, value)

var dismissibleItem = function (el, type, value) {
  var html =
    '<span>' + value + ' <button type="button" class="close">X</button></span>'

  el.classList.add('dismissible', 'dismissible-' + type)
  el.innerHTML = html
}

The dismissibleItem function contains our logic for handling each banner. Passing the data attribute values, here we set the HTML content for the banner div and attach some CSS classes for styling.

From the example above, on browser runtime this will produce the following HTML:

<div
  data-component="dismissible-item"
  data-type="info"
  data-value="<strong>Welcome message</strong>"
  class="dismissible dismissible-info"
>
  <span>
    <strong>Welcome message</strong>
    <button type="button" class="close">X</button>
  </span>
</div>

Let’s modify our dismissibleItem to remove the data attributes and clean-up the modified HTML now they are no longer required.

el.removeAttribute('data-component')
el.removeAttribute('data-type')
el.removeAttribute('data-value')

The last step is to add an eventListener for our close button, and handle a smooth transition to remove the banner.

function dismissBanner(event) {
  var height = el.offsetHeight,
    opacity = 1,
    timeout = null
  function reduceHeight() {
    height -= 2
    el.setAttribute('style', 'height: ' + height + 'px; opacity: ' + opacity)
    if (height <= 0) {
      window.clearInterval(timeout)
      timeout = null
      el.remove()
    }
  }
  function fade() {
    opacity -= 0.1
    el.setAttribute('style', 'opacity: ' + opacity)
    if (opacity <= 0) {
      window.clearInterval(timeout)
      timeout = window.setInterval(reduceHeight, 1)
    }
  }
  timeout = window.setInterval(fade, 25)
}

el.querySelector('.close').addEventListener('click', dismissBanner)

Within this event handler, we use window.setInterval to first gradually reduce the opacity of the banner to 0. Once the element is not visible, we can use window.setInterval again to animate the height of the banner also to 0. After this, we can remove the element from the DOM.

Code Example

codepen.io/matswainson/pen/PGrqGG