Home > Articles > Home & Office Computing > The Web/Virtual Worlds/Social Networking

Developing HTML5 Applications, Part 1

HTML5 is a hot topic these days, and you’ll probably want to create your own HTML5 applications. If these applications are to be useful, they should work in a wide variety of browsers. Author and web developer Jeff Friesen launches a three-part series that focuses on developing portable HTML5 applications. Specifically, the article overviews HTML5 features that are used by the larger applications presented later in this series, tests these features in various browsers to determine browser support, and introduces a JavaScript library whose browser-identification functions help in writing portable HTML5 applications.
Like this article? We recommend

HTML5 is a hot topic these days, and justifiably so because this next major revision of the HTML standard has much to offer for developing applications that run in the web browser. As the HTML5 specification and browser implementations of this specification mature, developers experienced in HTML, JavaScript, CSS, and DOM will be able to create powerful HTML5 applications.

Although the HTML5 specification is years away from being finalized, you can start to explore its goodies now because recent versions of major browsers (such as Mozilla Firefox) are already implementing many HTML5 features. Unfortunately, the level of support for various features varies from browser to browser, making it difficult to write portable HTML5 applications that take advantage of these features.

This article launches a three-part series that focuses on developing portable HTML5 applications. Part 1 presents an overview of HTML5, emphasizing features used by the larger applications revealed later in this series. It then tests these features in various browsers to determine browser support, and introduces a JavaScript library whose browser-identification functions help in writing portable HTML5 applications.

HTML5 Overview

HTML5 is the successor to the current HTML 4.01 standard. Its history dates back to June 2004, at which time the Web Hypertext Application Technology Working Group (WHATWG) began to work on HTML 4.01's successor under the name Web Applications 1.0. The World Wide Web Consortium (W3C) subsequently adopted (in 2007) WHATWG's specification as a starting point for HTML5.

The W3C's HTML5: A Vocabulary and Associated APIs for HTML and XHTML document provides the latest working draft of the HTML5 specification. If you find this lengthy reference difficult to process, check out Wikipedia's HTML5 entry for an abbreviated overview of what sets HTML5 apart from its predecessors.

HTML5 has much to offer; some of its many features are described in the following list:

  • A new audio element that represents a sound or audio stream.
  • A new canvas element that provides scripts with a resolution-dependent bitmap canvas, which can be used for rendering graphs, game graphics, or other visual images on the fly.
  • A new nav element representing a section of a page that links to other pages or to parts within the page.
  • A new video element for playing videos or movies.
  • An API for selecting files from the local filesystem and reading all or part of their data—see the W3C's companion File API document for more information.
  • An event-based drag-and-drop mechanism.
  • Support for microdata, which offers a simple way to embed semantic (meaningful) markup into HTML documents—see the W3C's companion HTML Microdata document for more information.
  • Support for spelling and grammar checking.
  • Support for web storage, which makes it possible to store structured data in key/value pairs on the client side—see the W3C's companion Web Storage document for more information.
  • The elimination of the center and font elements because their effects can be achieved through CSS.

The need for brevity prevents me from exploring all of the new features being introduced by HTML5. Instead, I focus only on the aforementioned audio, canvas, and File API features in the following sections, because I take advantage of these features in the HTML5 applications presented in the second and third parts of this series.

Audio

The audio element is represented in HTML via the <audio> and </audio> tags. Furthermore, the <audio> tag is defined to accept the following attributes:

  • src: A string attribute that must specify a valid nonempty URL (possibly surrounded by spaces) of an audio resource.
  • preload: An enumerated attribute that specifies whether or how the audio is preloaded; its value is one of "none" (do not preload the audio), "metadata" (preload metadata only), or "auto" (preload the entire audio resource if possible).
  • autoplay: A Boolean attribute that (when present) indicates automatic playback as soon as enough audio content has been downloaded so that playback can begin without stopping.
  • loop: A Boolean attribute that (when present) indicates that the audio should be replayed as soon as it finishes.
  • controls: A Boolean attribute that (when present) indicates that a user interface should be displayed so that the user can begin playback, pause playback, seek to an arbitrary position in the audio, change the volume, and so on.

Listing 1 codifies an audio element via the <audio> tag and its src and controls attributes. This listing's audio element plays an MP3-based audio resource of American composer Samuel Barber's Adagio for Strings composition.

Listing 1—AudioDemo.html

<html>
  <head>
    <title>
      Audio Demo
    </title>
  </head>
  <body>
    <audio src="http://lemalapo.20minutes-blogs.fr/media/01/01/111491075.mp3" 
           controls>
    </audio>
  </body>
</html>

The presence of the controls attribute causes the browser to render an appropriate user interface for playing and controlling music play. Figure 1 reveals this user interface in the context of the Google Chrome browser.

Figure 1 Chrome's user interface lets you play and control the play of an audio resource.

It's possible to programmatically play and control audio resources by using JavaScript's Audio type, which provides access to the properties and methods of the HTMLAudioElement DOM interface (a subinterface of HTMLMediaElement). Listing 2 provides a demonstration.

Listing 2—Playing Audio via JavaScript and the DOM

<script type="text/javascript">
var audio = new Audio();
audio.src = "http://lemalapo.20minutes-blogs.fr/media/01/01/111491075.mp3";
audio.play();
</script>

After constructing an Audio object via the Audio constructor, Listing 2 assigns the same URL to this object's src attribute as was specified in Listing 1. It then invokes Audio's play() method to start playing the audio resource.

Canvas

The canvas element is represented in HTML via the <canvas> and </canvas> tags. Furthermore, the <canvas> tag is defined to accept the following attributes:

  • width: A valid nonnegative integer attribute that specifies the canvas's width in pixels; if this attribute is missing, a default value of 300 pixels is used.
  • height: A valid nonnegative integer attribute that specifies the canvas's height in pixels; if this attribute is missing, a default value of 150 pixels is used.

Listing 3 codifies a canvas element via the <canvas> tag; its width and height attributes are set to 400 and 300 pixels, respectively. This listing also provides a script that accesses and draws on the canvas.

Listing 3—CanvasDemo.html

<html>
  <head>
    <title>
      Canvas Demo
    </title>
  </head>
  <body>
    <canvas id="mycanvas" width="400" height="300">
      The HTML5 canvas element is not supported by your browser.
    </canvas>
    <script type="text/javascript">
      var canvas = document.getElementById("mycanvas");
      var context = canvas.getContext("2d");
      context.fillRect(0, 0, 400, 300); // Render a black-filled rectangle
                                        // over the entire canvas.
      context.fillStyle = "rgb(255, 0, 0)"; // Specify red as the fill color.
      context.fillRect(30, 30, 340, 240); // Render a red-filled rectangle
                                          // leaving a 30-pixel black border.
    </script>
  </body>
</html>

Notice the text that appears between <canvas> and </canvas>. If a browser does not support the canvas element (Internet Explorer 8 is one example), the HTML located between these tags is rendered instead.

By itself, a canvas cannot generate graphics: It only defines the rectangular region on which graphics can be rendered. JavaScript (or another scripting language) is required to programmatically render graphics.

A script's first task is to obtain the DOM canvas object that corresponds to the <canvas> tag's id attribute. It accomplishes this task by calling the DOM's document object's getElementById(string) method with id's value as the method argument, as follows:

var canvas = document.getElementById("mycanvas");

After obtaining the canvas object, the script must obtain a drawing context for drawing on the canvas. It accomplishes this task by calling the getContext(string) method on the returned canvas object, as follows:

var context = canvas.getContext("2d");

This method assigns a nonnull object to context if the two-dimensional canvas API is supported. Otherwise, getContext() returns null. However, if a browser (such as Internet Explorer 8) doesn't support canvas, there is no getContext() method and the result is undefined.

Assuming that a nonnull context is returned, you can access various context properties (such as fillStyle, specify the current fill color, which defaults to black) and call various methods (such as fillRect(), draw a filled rectangle in the current fill style).

When you run this HTML5 application in a browser that supports the canvas element, you should observe the rendered canvas that appears in Figure 2.

Figure 2 Opera renders a red-filled rectangle over a black-filled rectangle.

File API

The File API makes it possible to select files in the local filesystem and read file content subject to the security considerations discussed in the W3C's File API document. This API consists of the following components:

  • A FileList property of the HTMLInputElement DOM interface that stores the sequence of files selected by the user from the local filesystem as an array of File objects.
  • A Blob DOM interface that represents raw binary data and allows access to ranges of bytes within the Blob object; this interface exposes a readonly size property that stores the size of a Blob object in bytes, and a slice(start, length) method that returns a new Blob object whose byte sequence begins at offset start and ends at offset start+length-1 within the current Blob object.
  • A File DOM interface that extends Blob and describes a single file in the FileList sequence; this interface exposes readonly name, type, and urn properties that store the name of the file without its path, the ASCII-encoded MIME type of the file, and the file's uniform resource name—urn might be renamed in the future.
  • A FileReader DOM interface that provides a noargument constructor, methods to asynchronously read a file (readAsBinaryString(blob) to read the file represented by the blob argument, for example), readonly properties (such as result, which stores the read file content in a string), and event handlers (such as onloadend—the assigned function is called when the read operation completes).
  • A FileError DOM interface for reporting errors originating from the asynchronous FileReader file-reading methods; FileReader provides a readonly error property of type FileError that stores the error code.
  • A FileReaderSync DOM interface that provides a noargument constructor, and methods to synchronously read a file (readAsDataURL(file) to read the file represented by the file argument, for example); apart from returning strings that contain file content, FileReaderSync's file-reading methods have the same method signatures as their FileReader counterparts.
  • A FileException exception DOM interface for reporting errors originating from the synchronous FileReaderSync file-reading methods; this exception is thrown in lieu of FileReaderSync providing an error property.

The File API is much easier to use than it might first appear. For example, Listing 4 provides a demonstration of the FileList, File, and FileReader portions of the API.

Listing 4—FileAPIDemo.html

<html>
  <head>
    <title>
      File API Demo
    </title>
  </head>
  <body>
    <input id="files list" type="file" multiple onchange="dumpFileInfo()">
    <p>
    <div id="output">
    </div>
    <script type="text/javascript">
       var files;
       function dumpFileInfo()
       {
          files = document.getElementById("files list").files;
          var output = document.getElementById("output");
          while (output.childNodes.length != 0)
             output.removeChild(output.firstChild);
             
          var table = document.createElement("table");
          table.setAttribute("border", "4");
          table.setAttribute("cellPadding", "5");
          var tHead = document.createElement("tHead");
          table.appendChild(tHead);
          table.tHead.appendChild(document.createElement("tr"));
          var td = document.createElement("td");
          td.appendChild(document.createTextNode("Name"));
          table.tHead.rows[0].appendChild(td);
          td = document.createElement("td");
          td.appendChild(document.createTextNode("Size"));
          table.tHead.rows[0].appendChild(td);
          var tbody = document.createElement("tbody");
          table.appendChild(tbody);
          for (var i = 0; i < files.length; i++)
          {
             table.tBodies[0].appendChild(document.createElement("tr"));
             td = document.createElement("td");
             var link = document.createElement("a");
             link.setAttribute("href", "javascript: dumpFile("+i+")");
             link.appendChild(document.createTextNode(files[i].name));
             td.appendChild(link);
             table.tBodies[0].rows[i].appendChild(td);
             td = document.createElement("td");
             td.appendChild(document.createTextNode(files[i].size));
             table.tBodies[0].rows[i].appendChild(td);
          }
          output.appendChild(table);
          output.appendChild(document.createElement("p"));
       }
       function dumpFile(i)
       {
          var fr = new FileReader();
          fr.onabort = function()
          {
             alert("abort");
          }
          fr.onerror = function()
          {
             var msg = "";
             switch (fr.error)
             {
                case FileError.NOT_FOUND_ERR:
                   msg = "not found";
                   break;
                case FileError.SECURITY_ERR:
                   msg = "security violation";
                   break;
                case FileError.ABORT_ERR:
                   msg = "abort";
                   break;
                case FileError.NOT_READABLE_ERR:
                   msg = "unreadable";
                   break;
                case FileError.ENCODING_ERR:
                   msg = "bad encoding";
                   break;
                default:
                   msg = "unknown";
             }
             alert(msg);
          }
          fr.onload = function()
          {
             alert("load");
          }
          fr.onloadstart = function()
          {
             alert("load start");
          }
          fr.onloadend = function()
          {
             alert("load end");
             if (output.lastChild.nodeName == "PRE")
                output.removeChild(output.lastChild);
             var pre = document.createElement("pre");
             output.appendChild(pre);
             var size = Math.min(128, files[i].size);
             for (var j = 0; j < size; j++)
             {
                var hex = fr.result.charCodeAt(j).toString(16);
                if (hex.length == 1)
                   hex += "0";
                pre.appendChild(document.createTextNode(hex));
                pre.appendChild(document.createTextNode(" "));
                if (j%16 == 15)
                {
                   pre.appendChild(document.createElement("br"));
                }
             }
          }
          fr.onprogress = function()
          {
             alert("progress");
          }
          fr.readAsBinaryString(files[i]);
       }
    </script>
  </body>
</html>

The <input id="files list" type="file" multiple onchange="dumpFileInfo()"> tag lets the user select one or more files via a file chooser dialog. The ability to select more than one file is indicated by the presence of Boolean attribute multiple.

The browser processes this tag by rendering a text field to display the selected file(s) and a button for activating the file chooser. The selection of a new file causes the JavaScript function assigned to the onchange attribute—dumpFileInfo()—to run.

dumpFileInfo() begins by accessing the sequence of selected files via expression document.getElementById("files list").files:

  • document.getElementById("files list") uses the DOM to obtain the input element.
  • .files returns a FileList instance that contains this element's files sequence; the first file is stored in files[0].

Much of the code in dumpFileInfo() is occupied with dynamically creating an HTML table containing selected filenames and their sizes. I chose to use a table so that I could nicely align the values in the size column.

The File API-related code consists of a for loop where i ranges from 0 through files.length, files[i].name (access the ith entry in the files property and return its name field), and files[i].size (access the ith entry in the files property and return its size field.

Each filename is converted into a link that causes the dumpFile(i) function to run when the link is clicked; i is a zero-based index into the files property's array, and its value corresponds to the clicked filename.

After instantiating FileReader via var fr = new FileReader();, dumpFile(i) assigns anonymous functions to this object's various event handler properties. It then executes fr.readAsBinaryString(files[i]); to read the chosen file's contents.

The file is read asynchronously on a background thread. When this operation completes successfully, the file's contents are stored in the FileReader object's result field, and the function assigned to onloadend executes.

After removing the previous pre element (if present), onloadend() converts no more than the first 128 bytes of the content stored in result to hexadecimal via expression fr.result.charCodeAt(j).toString(16), and adds these bytes to a dynamically created pre element.

To try out this application for yourself, start up a more recent version of the Firefox or Chrome browser. Figure 3 reveals this application in a Firefox context.

Figure 3 Firefox reveals the File API's usefulness for selecting and reading local files.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020