- •Contents at a Glance
- •Contents
- •Foreword
- •About the Authors
- •About the Technical Reviewer
- •Acknowledgments
- •Introduction
- •Who This Book Is For
- •An Overview of This Book
- •Example Code and Companion Web Site
- •Contacting the Authors
- •Overview of HTML5
- •The Story So Far—The History of HTML5
- •The Myth of 2022 and Why It Doesn’t Matter
- •Who Is Developing HTML5?
- •A New Vision
- •Compatibility and Paving the Cow Paths
- •Utility and the Priority of Constituencies
- •Interoperability Simplification
- •Universal Access
- •A Plugin–Free Paradigm
- •What’s In and What’s Out?
- •What’s New in HTML5?
- •New DOCTYPE and Character Set
- •New and Deprecated Elements
- •Semantic Markup
- •Simplifying Selection Using the Selectors API
- •JavaScript Logging and Debugging
- •window.JSON
- •DOM Level 3
- •Monkeys, Squirrelfish, and Other Speedy Oddities
- •Summary
- •Using the Canvas API
- •Overview of HTML5 Canvas
- •History
- •What Is a Canvas?
- •Canvas Coordinates
- •When Not to Use Canvas
- •Fallback Content
- •CSS and Canvas
- •Browser Support for HTML5 Canvas
- •Using the HTML5 Canvas APIs
- •Checking for Browser Support
- •Adding a Canvas to a Page
- •Applying Transformations to Drawings
- •Working with Paths
- •Working with Stroke Styles
- •Working with Fill Styles
- •Filling Rectangular Content
- •Drawing Curves
- •Inserting Images into a Canvas
- •Using Gradients
- •Using Background Patterns
- •Scaling Canvas Objects
- •Using Canvas Transforms
- •Using Canvas Text
- •Applying Shadows
- •Working with Pixel Data
- •Implementing Canvas Security
- •Building an Application with HTML5 Canvas
- •Practical Extra: Full Page Glass Pane
- •Practical Extra: Timing Your Canvas Animation
- •Summary
- •Working with Scalable Vector Graphics
- •Overview of SVG
- •History
- •Understanding SVG
- •Scalable Graphics
- •Creating 2D Graphics with SVG
- •Adding SVG to a Page
- •Simple Shapes
- •Transforming SVG Elements
- •Reusing Content
- •Patterns and Gradients
- •SVG Paths
- •Using SVG Text
- •Putting the Scene Together
- •Building an Interactive Application with SVG
- •Adding Trees
- •Adding the updateTrees Function
- •Adding the removeTree Function
- •Adding the CSS Styles
- •The Final Code
- •Summary
- •Working with Audio and Video
- •Overview of Audio and Video
- •Video Containers
- •Audio and Video Codecs
- •Audio and Video Restrictions
- •Browser Support for Audio and Video
- •Using the Audio and Video API
- •Checking for Browser Support
- •Accessibility
- •Understanding Media Elements
- •Working with Audio
- •Working with Video
- •Practical Extras
- •Summary
- •Using the Geolocation API
- •About Location Information
- •Latitude and Longitude Coordinates
- •Where Does Location Information Come From?
- •IP Address Geolocation Data
- •GPS Geolocation Data
- •Wi-Fi Geolocation Data
- •Cell Phone Geolocation Data
- •User–Defined Geolocation Data
- •Browser Support for Geolocation
- •Privacy
- •Triggering the Privacy Protection Mechanism
- •Dealing with Location Information
- •Using the Geolocation API
- •Checking for Browser Support
- •Position Requests
- •Building an Application with Geolocation
- •Writing the HTML Display
- •Processing the Geolocation Data
- •The Final Code
- •Practical Extras
- •What’s My Status?
- •Show Me on a Google Map
- •Summary
- •Using the Communication APIs
- •Cross Document Messaging
- •Understanding Origin Security
- •Browser Support for Cross Document Messaging
- •Using the postMessage API
- •Building an Application Using the postMessage API
- •XMLHttpRequest Level 2
- •Cross-Origin XMLHttpRequest
- •Progress Events
- •Browser Support for HTML5 XMLHttpRequest Level 2
- •Using the XMLHttpRequest API
- •Building an Application Using XMLHttpRequest
- •Practical Extras
- •Structured Data
- •Framebusting
- •Summary
- •Using the WebSocket API
- •Overview of WebSocket
- •Real-Time and HTTP
- •Understanding WebSocket
- •Writing a Simple Echo WebSocket Server
- •Using the WebSocket API
- •Checking for Browser Support
- •Basic API Usage
- •Building a WebSocket Application
- •Coding the HTML File
- •Adding the WebSocket Code
- •Adding the Geolocation Code
- •Putting It All Together
- •The Final Code
- •Summary
- •Using the Forms API
- •Overview of HTML5 Forms
- •HTML Forms Versus XForms
- •Functional Forms
- •Browser Support for HTML5 Forms
- •An Input Catalog
- •Using the HTML5 Forms APIs
- •New Form Attributes and Functions
- •Checking Forms with Validation
- •Validation Feedback
- •Building an Application with HTML5 Forms
- •Practical Extras
- •Summary
- •Working with Drag-and-Drop
- •Web Drag-and-Drop: The Story So Far
- •Overview of HTML5 Drag-and-Drop
- •The Big Picture
- •Events to Remember
- •Drag Participation
- •Transfer and Control
- •Building an Application with Drag-and-Drop
- •Getting Into the dropzone
- •Handling Drag-and-Drop for Files
- •Practical Extras
- •Customizing the Drag Display
- •Summary
- •Using the Web Workers API
- •Browser Support for Web Workers
- •Using the Web Workers API
- •Checking for Browser Support
- •Creating Web Workers
- •Loading and Executing Additional JavaScript
- •Communicating with Web Workers
- •Coding the Main Page
- •Handling Errors
- •Stopping Web Workers
- •Using Web Workers within Web Workers
- •Using Timers
- •Example Code
- •Building an Application with Web Workers
- •Coding the blur.js Helper Script
- •Coding the blur.html Application Page
- •Coding the blurWorker.js Web Worker Script
- •Communicating with the Web Workers
- •The Application in Action
- •Example Code
- •Summary
- •Using the Storage APIs
- •Overview of Web Storage
- •Browser Support for Web Storage
- •Using the Web Storage API
- •Checking for Browser Support
- •Setting and Retrieving Values
- •Plugging Data Leaks
- •Local Versus Session Storage
- •Other Web Storage API Attributes and Functions
- •Communicating Web Storage Updates
- •Exploring Web Storage
- •Building an Application with Web Storage
- •The Future of Browser Database Storage
- •The Web SQL Database
- •The Indexed Database API
- •Practical Extras
- •JSON Object Storage
- •A Window into Sharing
- •Summary
- •Overview of HTML5 Offline Web Applications
- •Browser Support for HTML5 Offline Web Applications
- •Using the HTML5 Application Cache API
- •Checking for Browser Support
- •Creating a Simple Offline Application
- •Going Offline
- •Manifest Files
- •The ApplicationCache API
- •Application Cache in Action
- •Building an Application with HTML5 Offline Web Applications
- •Creating a Manifest File for the Application Resources
- •Creating the HTML Structure and CSS for the UI
- •Creating the Offline JavaScript
- •Check for ApplicationCache Support
- •Adding the Update Button Handler
- •Add Geolocation Tracking Code
- •Adding Storage Code
- •Adding Offline Event Handling
- •Summary
- •The Future of HTML5
- •Browser Support for HTML5
- •HTML Evolves
- •WebGL
- •Devices
- •Audio Data API
- •Touchscreen Device Events
- •Peer-to-Peer Networking
- •Ultimate Direction
- •Summary
- •Index
CHAPTER 9 WORKING WITH DRAG-AND-DROP
<ul id="racers" dropzone=”copy s:text/plain s:text/html” ondrop=”handleDrop(event)”>
This provides a quick way of telling the browser that copy operations for elements that support either the plain text or HTML data format are allowed to drop on our list.
The dropzone is not supported by most major browser vendors at the time of writing, but support for it is likely forthcoming.
Handling Drag-and-Drop for Files
If you’ve ever wanted an easier way to add files to your web application, or you’ve wondered how some of the newest sites allow you to drag files directly into a page and upload them, the answer is the HTML5 File API. Although the size and status of the entire W3C File API is out of scope for this discussion, many browsers already support a subset of the standard, which allows files to be dragged into an application.
Note The W3C File API is documented online at www.w3.org/TR/FileAPI.
The File API contains functionality for asynchronously reading files in a web page, uploading them to servers while tracking process, and turning files into page elements. However, affiliated specifications such as drag-and-drop use a subset of the File API, and that is the area where we will focus our attention in this chapter.
Recall that we’ve already alluded to file drag-and-drop twice in this chapter. First, the dataTransfer object contains a property named files, which will contain a list of files attached to the drag, if appropriate. For example, if a user drags a file or set of files in from the desktop into your application’s web page, the browser will fire drag-and-drop events where the dataTransfer.files object has a value. Additionally, browsers that support the previously mentioned dropzone attribute allow files of specific MIME types to be valid drops on an element by using the f: MIME type prefix.
Note Currently, the Safari browser only supports drag-and-drop operations for files. Drags initiated inside a page will fire most drag-and-drop events, but drop events only occur if the type of drag is a file.
As usual, you cannot access the files during most drag-and-drop events, because they are protected for security reasons. Although some browsers might let you get access to the list of files during drag events, no browser will let you get access to the file data. In addition, the dragstart, drag, and dragend events that are fired at the drag source element are not triggered in a file drag-and-drop, as the source is the file system itself.
The file items in our file list support the following properties:
•name: The full filename with extension
•type: The MIME type of the file
•size: The size of the file in bytes
•lastModifiedDate: The timestamp for when the file contents were last modified
235
CHAPTER 9 WORKING WITH DRAG-AND-DROP
Let’s walk through a simple example of file drag-and-drop where we will show the characteristics of any file dropped onto our page, shown in Figure 9-5. This code is contained in the fileDrag.html example included with the book.
Figure 9-5. Demo page displaying the characteristics of dropped files
The HTML for our demo is actually quite simple (see Listing 9-13).
Listing 9-13. Markup for File Drop Demo
<body>
<div id="droptarget"> <div id="status"></div> </div>
</body>
We have only two elements in the page. A drop target where files will be dropped and a status display area.
As with our last example, we will register drag-and-drop event handlers during page load (see Listing 9-14).
236
CHAPTER 9 WORKING WITH DRAG-AND-DROP
Listing 9-14. Loading and Initialization Code for File Drop Demo
var droptarget;
//set the status text in our display function setStatus(text) {
document.getElementById("status").innerHTML = text;
}
//...
function loadDemo() {
droptarget = document.getElementById("droptarget"); droptarget.className = "validtarget";
droptarget.addEventListener("dragenter", handleDragEnter, false); droptarget.addEventListener("dragover", handleDragOver, false); droptarget.addEventListener("dragleave", handleDragLeave, false); droptarget.addEventListener("drop", handleDrop, false);
setStatus("Drag files into this area.");
}
window.addEventListener("load", loadDemo, false);
This time, the drop target receives all of the event handlers. Only a subset of handlers is needed, and we can ignore events that take place at the drag source.
When the user drags files into our drop target, we will display what we know about the drop candidates (see Listing 9-15).
Listing 9-15. File Drop Drag Enter Handler
// handle drag events in the drop target function handleDragEnter(evt) {
//if the browser supports accessing the file
//list during drag, we display the file count var files = evt.dataTransfer.files;
if (files)
setStatus("There are " + evt.dataTransfer.files.length + " files in this drag.");
else
setStatus("There are unknown items in this drag.");
droptarget.className = "highlighted";
evt.stopPropagation();
evt.preventDefault();
237
w
CHAPTER 9 WORKING WITH DRAG-AND-DROP
return false;
}
Although some browsers allow access to the dataTransfer files mid-drag, we will handle the case where that information is off-limits. When the count is known, we will display it in the status.
Handling dragover and dragleave events is straightforward (see Listing 9-16).
Listing 9-16. File drop dragover and dragleave Handlers
//preventing the default dragover behavior
//is necessary for successful drops function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
return false;
}
// reset the text and status when drags leave function handleDragLeave(evt) {
setStatus("Drag files into this area.");
droptarget.className = "validtarget";
return false;
}
As always, we must cancel dragover events to allow drops to be handled by our own code rather than the browser’s default behavior, which is usually to display them inline. For a dragleave, we only set the status text and style to indicate that drops are no longer valid when the mouse leaves. The bulk of our work is done in the drop handler (see Listing 9-17).
Listing 9-17. File Drop Handler
// handle the drop of files function handleDrop(evt) {
// cancel the event to prevent viewing the file evt.preventDefault();
evt.stopPropagation();
var filelist = evt.dataTransfer.files;
var message = "There were " + filelist.length + " files dropped.";
// show a detail list for each file in the drag message += "<ol>";
[].forEach.call(filelist, function(file) { message += "<li>";
message += "<strong>" + file.name + "</strong> "; message += "(<em>" + file.type + "</em>) : ";
238