Enhancing User Experience: Missing chapter of my book `Unlocked JavaScript`

HTML5

My book “Unlocked JavaScript” (https://www.packtpub.com/web-development/javascript-unlocked) has been released on December 7, 2015.

This book is for developers already familiar with JavaScript who want to level up to get the most out of the language. The book is practice–oriented and would be most helpful for those who is used to learn by doing as the topics are thoroughly covered with real-life examples and tutorials. This is an extract of a chapter not included in the book.

As you likely know, in addition to new syntax, HTML5 introduces powerful features and APIS that can be used with JavaScript. Some of them such as Web Storage, IndexDB, FileSystem, Workers, Custom Elements, HTML Imports, Shadow DOM and Templates we examine in the book. Here I want to share with you a few HTML5 API that you may not be even aware of. Nonetheless they may help you to improve UX in your web application significantly.

Notification API

What the options do we have to notify user about anything? We use alert()… Oh no, just joking. Usually we write custom components that pop up

somewhere within the application viewport. But what if the notification happens when the application window/tab is inactive? It still shows up,

but user stays unaware about. Can we somehow improve that user experience? Yes, we can, by using HTML5 Notification API. We just need to create Notification object

by setting title text and optionally body text and icon URL. Here is only one difficulty. Notification shall be allowed by user as it’s up to user to decide either they are ok

with web application firing notification on a desktop or not. So prior to creating a notification we have to check if the app has the corresponding permissions and if not we request them from the user:

<!DOCTYPE html>
<html>
  <head>
    <title>Notification API Demo</title>
  </head>
  <body>
    <button>Notify</button>
    <script>
          /** @type {HTMLElement} */
      var button = document.querySelector( "button" ),
          /**
           * Show the notification for 3 sec
           */
          fireNotification = function(){
            var notification = new Notification( "Wake up!", {
              body: "You've got Email",
              icon: "http://dsheiko.com/download/email.png"
            });
           setTimeout( notification.close.bind( notification ), 3000 );
          },
          /**
           * Handle button "click" event
           */
          onClick = function() {
            // Permission is granted: Greenlight
            if ( Notification.permission === "granted" ) {
              return fireNotification();
            }
            // Oops, we need to ask the user for permission
            if ( Notification.permission !== "denied" ) {
              Notification.requestPermission(function( permission ) {
                // User accepts, so we go on
                permission === "granted" %26%26 fireNotification();
              });
            }
          };

      button.addEventListener( "click", onClick, false );
    </script>
  </body>
</html>

Here how it works. When the button is clicked this demo shows a desktop notification for 3 seconds then remove it. Of course it can be displayed only if user didn’t deny the corresponding permission for the application.

Enhancing User Experience: Missing chapter of my book `Unlocked JavaScript`

Credits

For the notification icon was used a work of Bartlomiej Jacak (http://bartek.xyz) licensed under the Creative Commons (Attribution 3.0 Unported)

Visibility API

Have you ever ran into the issue where your web page plays a video and when user switching between tab the video still running despite its tab is inactive?

So the page with the video is out of the view, yet it streams taking resources. Besides it’s not muted. Fortunately that is something that we can improve.

Whenever user enters or leaves a window or tab document.hidden property reflects the state and “visibilitychange” event is being fired on the document.

Keeping this in mind, we can subscribe a handler on this event that would stop videos on the page if the document gets hidden (window inactive):

<!DOCTYPE html>
<html>
  <head>
    <title>Visibility API Demo</title>
    <style>
      html {
        background: #282c2b;
      }
    </style>
  </head>
  <body>
    <video preload autoplay loop>
      <source type="video/ogg" src="http://download.blender.org/peach/trailer/trailer_400p.ogg" ></source>
    </video>
    <script>
          /** @type {HTMLElement} */
      var video = document.querySelector( "video" ),
          /**
           * Handle document's "visibilitychange" event
           */
          onVisibilityChange = function(){
            if ( document.hidden ) {
              return video.pause();
            }
            video.play();
          },
          /**
           * Handle video "timeupdate" event
           */
          onTimeupdate = function(){
            document.title = Math.floor( video.currentTime ) + " second(s)";
          };

    document.addEventListener( "visibilitychange", onVisibilityChange, false );
    video.addEventListener( "timeupdate", onTimeupdate, false );

    </script>
  </body>
</html>

This example updates window title with actual video playback time in seconds. So you can see it is being changed while video is playing.

Enhancing User Experience: Missing chapter of my book `Unlocked JavaScript`

However as we jump to another tab the title of page with the video stops changing. In Chrome you can see that the little audio icon normally accompanying tabs that play video/audio also fades down.

Enhancing User Experience: Missing chapter of my book `Unlocked JavaScript`

Fullscreen mode

Fullscreen API allows us programmatically switching the browser into fullscreen mode. So imagine we have on a page a widget running a canvas game or video.

By clicking on it we give it the whole screen achieving the true desktop application experience. I the example below we subscribe a handler to the button under the video that toggle the fullscreen mode.

<!DOCTYPE html>
<html>
  <head>
    <title>Fullscreen API Demo</title>
    <style>
      html {
        background: #282c2b;
      }
    </style>
  </head>
  <body>
    <video preload autoplay loop>
      <source type="video/ogg" src="http://download.blender.org/peach/trailer/trailer_400p.ogg" ></source>
    </video>
    <button>Toggle Fullscreen</button>
    <script>
          /** @type {HTMLElement} */
      var video = document.querySelector( "video" ),
          /** @type {HTMLElement} */
          button = document.querySelector( "button" ),
          /**
           * Toggle fullscreen
           */
          toggleFullScreen = function() {
            if ( !video.webkitRequestFullscreen() ) {
              return video.webkitRequestFullscreen();
            }
            video.webkitExitFullscreen();
          },
          /**
           * Handle Esc pressed
           * @param {Event} e
           */
          onPressEsc = function( e ){
            e.keyCode === 13 %26%26 toggleFullScreen();
          },
          /**
           * Handle button "click" event
           * @param {Event} e
           */
          onClick = function( e ){
            e.preventDefault();
            toggleFullScreen();
          };

    document.addEventListener( "keydown", onPressEsc, false );
    button.addEventListener( "click", onClick, false );

    </script>
  </body>
</html>

Unfortunately the methods of this API are still under vendor prefixes. The example will only work in Chrome.

Enhancing User Experience: Missing chapter of my book `Unlocked JavaScript`
Enhancing User Experience: Missing chapter of my book `Unlocked JavaScript`

Credits

In the examples above there was used Big Buck Bunny trailer (https://peach.blender.org), which is part of Open Project hosted by the Blender Institute and licensed under the Creative Commons Attribution 3.0 (https://peach.blender.org/about/)