Skip to content

Create toast notifications with pure JavaScript

We are going to create a toast notifications plugin with pure JavaScript in this tutorial. A toast notification is a small message that is shown over other contents.

This notification plugin is able to show different messages. Notifications can be shown during a limited time, this is visualized by a progress bar. A notification that gets focus will restart it’s self-destruction process. A notification can be closed and all notifications can be removed by calling the clear method.

This plugin depends on annytab.effects and Font Awesome, these dependencies can easily be replaced by you if you want to use other icons and/or another library for effects.

This plugin has been tested and is working with Google Chrome (75.0.3770.100), Mozilla Firefox (67.0.4), Microsoft Edge (42.17134.1.0), without any polyfill. It works in Internet Explorer (11.829.17134.0) with a polyfill for CustomEvent. If you want to support older browsers, check out our post on transpilation and polyfilling of JavaScript.

Toast notifications

JavaScript

This plugin does not have a constructor, it is static and can be used by calling the public methods: setOptions, show and clear. Notifications is created in a container and the container is removed when the last message is removed.

  1. var annytab = annytab || {};
  2. annytab.notifier = (function () {
  3. 'use_strict';
  4. // Variables
  5. var options = { duration: 10000, position: 'top-center', fade_duration: 1000 };
  6. var container = null;
  7. // Update options
  8. function updateOptions(opts)
  9. {
  10. // Set default values for parameters
  11. opts = opts || {};
  12. // Update options
  13. for (var option in options)
  14. {
  15. if (opts.hasOwnProperty(option) === true)
  16. {
  17. options[option] = opts[option];
  18. }
  19. }
  20. // Return options
  21. return options;
  22. } // End of the updateOptions method
  23. // Create a box
  24. function create(type, message)
  25. {
  26. // Make sure that a container exists
  27. if (container === null)
  28. {
  29. container = document.createElement('div');
  30. container.setAttribute('class', 'annytab-notifier-container annytab-notifier-' + options.position);
  31. document.body.appendChild(container);
  32. }
  33. // Set icon (Font Awesome)
  34. var icon = '<i class="fas fa-exclamation fa-fw"></i>';
  35. if (type === 'success') { icon = '<i class="fas fa-check-circle fa-fw"></i>'; }
  36. else if (type === 'warning') { icon = '<i class="fas fa-exclamation-triangle fa-fw"></i>'; }
  37. else if (type === 'info') { icon = '<i class="fas fa-info-circle fa-fw"></i>'; }
  38. // Create a box
  39. var box = document.createElement('div');
  40. box.setAttribute('class', 'annytab-notifier-box annytab-notifier-' + type);
  41. box.insertAdjacentHTML('beforeend',
  42. '<div class="annytab-notifier-padding">'
  43. + '<div class="annytab-notifier-icon">' + icon + '</div>'
  44. + '<div class="annytab-notifier-message">'
  45. + message
  46. + '</div>'
  47. + '<div class="annytab-notifier-progress"></div>'
  48. + '<div class="annytab-notifier-close"></div >');
  49. + '</div>';
  50. container.appendChild(box);
  51. // Fade in the message box
  52. annytab.effects.fadeIn(box, options.fade_duration, 'block');
  53. // Add events
  54. addBoxEvents(box);
  55. // Return the box
  56. return box;
  57. } // End of the create method
  58. // Add box events
  59. function addBoxEvents(box)
  60. {
  61. // Variables
  62. var close_button = box.querySelector('.annytab-notifier-close');
  63. var progress = box.querySelector('.annytab-notifier-progress');
  64. var progress_interval = null;
  65. var close_timeout = null;
  66. // Add a close event
  67. window.onload = close_button.addEventListener('click', function (event) {
  68. // Prevent default click behaviour
  69. event.preventDefault();
  70. // Close the box
  71. close(box);
  72. }, false);
  73. // Check if the box should self destruct
  74. if (options.duration > 0)
  75. {
  76. // Add self destruction event
  77. window.onload = box.addEventListener('mouseleave', function (event) {
  78. // Prevent default click behaviour
  79. event.preventDefault();
  80. // Check if the box is closing
  81. if (annytab.effects.isVisible(close_button) === false) {
  82. return;
  83. }
  84. // Display the progress bar
  85. progress.style.display = 'block';
  86. // Calculate the amount to decrease each interval
  87. var width = 100;
  88. var decrease = width / options.duration * 10;
  89. // Set an interval to show progress
  90. progress_interval = window.setInterval(function () {
  91. width -= decrease;
  92. progress.style.width = width + '%';
  93. }, 10);
  94. // Self destruct after some time
  95. close_timeout = window.setTimeout(function () {
  96. // Clear timeout and interval
  97. clearTimeout(close_timeout);
  98. clearInterval(progress_interval);
  99. // Close the box
  100. close(box);
  101. }, options.duration);
  102. }, false);
  103. // On focus
  104. window.onload = box.addEventListener('mouseenter', function (event) {
  105. // Prevent default click behaviour
  106. event.preventDefault();
  107. // Check if the box is closing
  108. if (annytab.effects.isVisible(close_button) === false)
  109. {
  110. return;
  111. }
  112. // Clear timeout and interval
  113. clearTimeout(close_timeout);
  114. clearInterval(progress_interval);
  115. // Reset progress bar
  116. progress.style.display = 'none';
  117. progress.style.width = '100%';
  118. }, false);
  119. // Trigger a mouse leave event
  120. box.dispatchEvent(new Event('mouseleave'));
  121. }
  122. } // End of the addBoxEvents method
  123. // Close a box
  124. function close(box)
  125. {
  126. // Get the close button
  127. var close_button = box.querySelector('.annytab-notifier-close');
  128. // Check if the box is closing
  129. if (annytab.effects.isVisible(close_button) === false) {
  130. return;
  131. }
  132. // Hide the close button
  133. close_button.style.display = 'none';
  134. // Fade out the box
  135. annytab.effects.fadeOut(box, options.fade_duration);
  136. // Wait for the fade effect to finish
  137. setTimeout(function ()
  138. {
  139. // Remove the box
  140. container.removeChild(box);
  141. // Check if we should remove the container
  142. if (container.querySelector('.annytab-notifier-box') === null) {
  143. document.body.removeChild(container);
  144. container = null;
  145. }
  146. }, options.fade_duration);
  147. } // End of the close method
  148. // Remove a container
  149. function removeContainer()
  150. {
  151. // Make sure that the container exists
  152. if (container !== null)
  153. {
  154. // Get all boxes in the container
  155. var boxes = container.querySelectorAll('.annytab-notifier-box');
  156. // Loop boxes
  157. for (var i = 0; i < boxes.length; i++) {
  158. // Close the box
  159. close(boxes[i]);
  160. }
  161. }
  162. } // End of the removeContainer method
  163. // Public methods
  164. return {
  165. setOptions: function (opts) {
  166. return updateOptions(opts);
  167. },
  168. show: function (type, message)
  169. {
  170. return create(type, message);
  171. },
  172. clear: function ()
  173. {
  174. removeContainer();
  175. }
  176. };
  177. })();

Styling (CSS)

The container for notifications can be set at various positions on the screen, the center-center position might look a little blurry. The close button is created entirely in CSS and icons comes from Font Awesome.

  1. /* Containers */
  2. .annytab-notifier-container {
  3. display: block;
  4. z-index: 200;
  5. position: fixed;
  6. max-width: calc(100% - 10px); /* adjust for margin */
  7. max-height: 100%;
  8. overflow: auto;
  9. }
  10. /* General styles */
  11. .annytab-notifier-box {
  12. display: none;
  13. position: relative;
  14. margin: 5px;
  15. width: 500px;
  16. max-width: calc(100% - 10px); /* adjust for margin */
  17. -webkit-box-sizing: border-box;
  18. -moz-box-sizing: border-box;
  19. box-sizing: border-box;
  20. }
  21. .annytab-notifier-padding {
  22. display: block;
  23. padding: 15px 15px 15px 65px;
  24. text-align: left;
  25. }
  26. .annytab-notifier-icon {
  27. display: inline-block;
  28. position: absolute;
  29. font-size: 28px; /* 32px is actual height */
  30. top: calc(50% - 16px);
  31. left: 15px;
  32. margin: auto;
  33. }
  34. .annytab-notifier-message {
  35. font-size: 16px;
  36. line-height: 24px;
  37. }
  38. .annytab-notifier-progress {
  39. display: none;
  40. position: absolute;
  41. left: 0;
  42. bottom: 0;
  43. width: 100%;
  44. height: 4px;
  45. background-color: #d9d9d9;
  46. }
  47. /* Box positions */
  48. .annytab-notifier-top-left {
  49. top: 5px;
  50. left: 5px;
  51. }
  52. .annytab-notifier-top-center {
  53. top: 5px;
  54. left: 50%;
  55. -ms-transform: translateX(-50%);
  56. transform: translateX(-50%);
  57. }
  58. .annytab-notifier-top-right {
  59. top: 5px;
  60. right: 5px;
  61. }
  62. .annytab-notifier-center-center {
  63. top: 50%;
  64. left: 50%;
  65. -ms-transform: translate(-50%, -50%);
  66. transform: translate(-50%, -50%);
  67. }
  68. .annytab-notifier-bottom-left {
  69. bottom: 5px;
  70. left: 5px;
  71. }
  72. .annytab-notifier-bottom-center {
  73. bottom: 5px;
  74. left: 50%;
  75. -ms-transform: translateX(-50%);
  76. transform: translateX(-50%);
  77. }
  78. .annytab-notifier-bottom-right {
  79. bottom: 5px;
  80. right: 5px;
  81. }
  82. /* Message types */
  83. .annytab-notifier-success {
  84. background-color: #ffffff;
  85. border: 4px solid #51A351;
  86. color: #51A351;
  87. }
  88. .annytab-notifier-error {
  89. background-color: #ffffff;
  90. border: 4px solid #BD362F;
  91. color: #BD362F;
  92. }
  93. .annytab-notifier-info {
  94. background-color: #ffffff;
  95. border: 4px solid #2F96B4;
  96. color: #2F96B4;
  97. }
  98. .annytab-notifier-warning {
  99. background-color: #ffffff;
  100. border: 4px solid #CC7606;
  101. color: #CC7606;
  102. }
  103. /* Close button */
  104. .annytab-notifier-close
  105. {
  106. position: absolute;
  107. width: 12px;
  108. height: 12px;
  109. top: 2px;
  110. right: 2px;
  111. cursor: pointer;
  112. }
  113. .annytab-notifier-close:before, .annytab-notifier-close:after {
  114. position: absolute;
  115. right: 5px;
  116. content: ' ';
  117. height: 12px;
  118. width: 2px;
  119. background-color: #000000;
  120. }
  121. .annytab-notifier-close:before {
  122. transform: rotate(45deg);
  123. }
  124. .annytab-notifier-close:after {
  125. transform: rotate(-45deg);
  126. }

How to use this plugin

You can set options before you start to call methods in the plugin, default values will be used if you don’t set any options. Set the duration to a value less than 1 if you do not want notifications to be shown during a limited time, notifications have to be closed or cleared in that case.

  1. <!--<script src="https://polyfill.io/v3/polyfill.min.js?features=CustomEvent"></script>-->
  2. <link href="/css/annytab.notifier.css" rel="stylesheet" />
  3. <script src="/js/font-awesome/v5.3.1/all.min.js"></script>
  4. <script src="/js/annytab-shared/annytab.effects.js"></script>
  5. <script src="/js/annytab-shared/annytab.notifier.js"></script>
  6. <script>
  7. // Set options
  8. // Positions: top-left, top-center, top-right, center-center, bottom-left, bottom-center, bottom-right
  9. annytab.notifier.setOptions({ duration: 10000, position: 'top-right', fade_duration: 1000 });
  10. // Show success
  11. annytab.notifier.show('success', 'Success, everything was perfect!');
  12. // Show error
  13. annytab.notifier.show('error', 'Something is wrong, it can be that or that.');
  14. // Show information
  15. annytab.notifier.show('info', 'I just want to inform you that it is going to rain today.');
  16. // Show warning
  17. annytab.notifier.show('warning', 'Warning for Internet Explorer, the worst browser that exists.');
  18. </script>

Leave a Reply

Your email address will not be published. Required fields are marked *