Getting Started with HTML5 Drag and Drop Part IV: Multiple Draggables and Multiple Droppables

HTML5

HTML5 LogoOnce you know how to successfully drag one HTML element and drop it on another one, there is a new UX challenge: multiple elements that can be dragged and then dropped on any one of multiple droppables.

In Parts I, II and III of this series, we covered the critical concepts needed to implement HTML drag and drop. There, we talked about the dragstart event, the dataTransfer object, originalEvent object, drop event, dragenter event, dragleave event, and setDragImage method. These concepts got us to the point where we could drag one HTML element, and then drop it on another. All of this, with some UX considerations such as setting a custom drag image, updating the droppable element when something is dragged over it or when something is dropped on it.

When I was taking a deep dive into HTML5 drag-and-drop, I wanted to be able to wire-up a scenario where there were multiple “draggable” elements, and multiple “droppable” elements. So from a UX standpoint, my goals were:

  1. Any draggable could be dropped on any droppable
  2. Each droppable would change appearance when an element was dragged over it
  3. Each droppable would change appearance when an element was dropped onto it
  4. Each droppable would accept only one dropped element at a time
  5. The container that originally held the droppables would change appearance when empty
  6. The container that originally holds the droppables could accept any one or all of the droppables if they are dragged back to it

When I first attempted this, I got to a point where this all seemed like a lot of moving parts. Fortunately, a substantial portion of the challenge has been solved in parts I, II and III of this series, and I hope that if you have already read those articles, you have a solid understanding of how to do the following:

  1. Make an element draggable
  2. Set a custom drag element
  3. Make an element droppable
  4. Update the droppable when an element is dragged over it
  5. Update the droppable when an element was dropped onto it

So with that knowledge, our task list shrinks a bit:

  1. Any draggable can be dropped on any droppable
  2. Each droppable will accept only one dropped element at a time
  3. The container that originally held the droppables will change appearance when empty
  4. The container that originally held the droppables will accept any one or all of the droppables if they are dragged back to it

From here on, I will walk through the steps I took to accomplish these goals. There are probably other ways to go about solving these problems, but I am sharing the approach I took.

Task # 1: Any draggable can be dropped on any droppable

Well this was the easiest step. In parts I, II and III of this series, all of the JavaScript event binding was accomplished using classes instead of IDs. Because of this, adding more draggables and droppables in the HTML solved this problem. The existing JavaScript worked fine.

Task # 2: Each droppable will accept only one dropped element at a time

There are two things I needed to do in order to solve this problem: 1) create two separate “drop” event handlers, one for the multiple droppable HTML elements and another for the container that originally held the droppables; 2) in “drop” event handlers of the multiple droppables, check to see if the droppable element already has a child element.

Before I discuss the fix for task # 2, take a look at this JSFiddle link: http://jsfiddle.net/v9hawcof/5/

That link demonstrates the behavior that I do NOT want: more than one draggable can be dropped onto a droppable.

Base HTML

So in the code example above, we have the base HTML for the rest of the examples in this article. For brevity’s sake, I’ve stripped out all but the most essential areas of the markup so that you can focus on the technologies demonstrated in this article. When you view the page source for the final working example, you will see that there is more HTML, but it is for presentational purposes only.

Example # 1

Here is the JSfiddle link for Example # 1: http://jsfiddle.net/v9hawcof/6/

Now in Example # 1, I’ve added a new function called: “dropHandlerSingle”. This event handler is dedicated to the four light brown boxes at top (i.e. the “multiple droppables”). In the function I check to see if the droppable element has any children. If so, then I exit immediately. You may also notice that I trigger this custom event: “custom:dropEvent”. That will be explained shortly.

Task # 3: The container that originally held the droppables will change appearance when empty

Example # 2

Here is the JSfiddle link for Example # 2: http://jsfiddle.net/v9hawcof/7/

In Example # 2, you see the event handler for “custom:dropEvent”. The reason I used the setTimeout method, is because of timing challenges. When the drop event occurs, the DOM is not in the state needed in order to query it and figure out what is going on (i.e. which droppable elements have children). This event handler for “custom:dropEvent” will check each droppable element, and if it has no children, it removes the CSS class that gives it a “hasChildren” appearance (i.e. the background color changes from dark brown to light brown).

Task # 4: The container that originally held the droppables will change appearance when empty

Example # 3A

Example # 3B

Example # 3C

 Here is the JSfiddle link for Example # 3: http://jsfiddle.net/v9hawcof/8/

In Example # 3A, I bind an event handler for the container that originally held the droppables. In Example # 3B you’ll see that event handler: the “dropHandlerMultiple” function. The “dropHandlerMultiple” event handler does pretty much the same thing as the “dropHandlerSingle” event handler. The only difference is that the “dropHandlerMultiple” function does not check to see if it has children already. This is the critical step in accomplishing task # 4. In Example # 3B, you’ll see the code that tells the dragenter event handler to exit immediately if an element is dragged over the container that originally held the droppables. This is not a critical feature. I suppose I could have allowed the dragenter UX to apply to that container as well.

Here is the working example for this article: http://examples.kevinchisholm.com/html5/drag-and-drop/part-iv.html

Here is the JavaScript for this article’s working example: http://examples.kevinchisholm.com/html5/drag-and-drop/js/part-iv.js

Summary

As you can see, everything in this article is really a matter of personal choice. What I’ve done is detail how I decided to solve a particular UX challenge. Now how you approach this same set of tasks is completely up to you. I found that while attempting all of this, I learned a few things about HTML5 drag and drop. I hope you will too.

Getting Started with HTML5 Drag and Drop Part III: Setting a Custom Drag Image

HTML5

HTML5 LogoLearn how to set a custom drag image for a better drag and drop UX.

In previous articles of this series: “Getting Started with HTML5 Drag and Drop Part I: Introduction,” and “Getting Started with HTML5 Drag and Drop Part II: The dragenter and dragleave Events,” we covered the basics needed to implement HTML5 drag and drop. The second article focused on the UX for dropping a dragged element. In this article, we will cover a UX consideration for dragging: setting a custom drag image.

When dragging a draggable HTML element, the default drag image is the element being dragged. In most cases, this is probably just fine. But what about if you want to snazz-up the UX and specify a custom image for the drag operation?

Using an image that already exists on the page

When using an image that already exists in the page as your custom drag image, there are two restrictions:

  1. The image must exist in the DOM (i.e. it cannot have its “display” property set to “none,” or “visibility: hidden.”
  2. The image must be visible on the page (i.e. it must be visible without scrolling)

Example # 1

(for the base HTML, please refer to either Part I or Part II of this series; they both provide that markup).

Here is the JSfiddle link for Example # 1: http://jsfiddle.net/v9hawcof/3/

The setDragImage Method

In Example # 1, we have set the HTML5 logo as the custom drag image. We do this by using the document.getElementsByClassName method. Since this method returns an HTMLcollection, we reference the element by using the [0] property as we know we will only get one element back (yes, we could have used the document.getElementbyId method, but I wanted to keep the HTML clean).

There are a couple of drawbacks to this approach

  1. The HTML5 logo must be visible in the DOM, which is a bit restrictive
    Some browsers (e.g. Firefox) will display the image in its native size, whereas others (e.g. Google Chrome) might display it using the dimensions defined by its current CSS
  2. Using an external image for the custom drag image

Example # 2

Here is the JSfiddle link for Example # 2: http://jsfiddle.net/v9hawcof/4/

In Example # 2, we use an external image for our custom drag image. In this case it’s a silly image of Bart Simpson on his surfboard, but you can certainly use any image you desire. The advantage here is that we have much more control over the experience. We can use any image we like, and we don’t need to worry about whether or not the image we use is part of or visible in the DOM; it’s external to the DOM. Of course, you can use an image that already exists in the DOM, but you gain the greatest control when you create a new image, rather than use a reference to a DOM element.

Here is the working example for this article: http://examples.kevinchisholm.com/html5/drag-and-drop/part-iii.html

Here is the JavaScript for this article’s working example: http://examples.kevinchisholm.com/html5/drag-and-drop/js/part-iii.js

Summary

Setting a custom drag image may seem like icing on the cake, but it is not an uncommon case. In this article we discussed two options: using a reference to an existing image element in the DOM, as well as using an external image. There is no right or wrong answer as to which approach is best, but I hope this article has not only explained how to do this, but the pros and cons of each method.

Helpful Links for the HTML5 Drag and Drop setDragImage Method

https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer#setDragImage.28.29

http://help.dottoro.com/ljdpgfkx.php

http://stackoverflow.com/questions/16894049/feature-detection-for-setdragimage-of-html5-drag-and-drop

Getting Started with HTML5 Drag and Drop Part II: The dragenter and dragleave Events

HTML5

HTML5 LogoGetting HTML5 drag and drop to work is a great start, but taking this to production requires certain UX considerations.

In the previous article of this series: “Getting Started with HTML5 Drag and Drop Part I: Introduction,” we covered the bare minimum code needed to make an HTML element draggable, and droppable onto another element. So, in Part II of this series, I will talk about two events that allow for better UX with regard to any element onto which you might drop something.

When I say: “…..any element onto which you might drop something,” I am referring to the fact that dragging something does not always mean that you will definitely drop it. In most drag and drop scenarios, you have one or more elements to drag, but also multiple places where you may drop them. Therefore, it is most often a good idea to give the user some indication that the element that they are dragging could be dropped in a particular location. Consequently, this involves setting up a hover-like behavior where the droppable element reacts to the fact that a draggable element has been dragged over it, or dragged away from it.

HTML Base

In the code example above, we have the base HTML for the rest of the examples in this article. For brevity’s sake, I’ve stripped out all but the most essential areas of the markup so that you can focus on the technologies demonstrated in this article. When you view the page source for the final working example, you will see that there is more HTML, but it is for presentational purposes only.

Example # 1

Here is the JSfiddle link for Example # 1: http://jsfiddle.net/v9hawcof/

The dragenter Event

In Example # 1A, we bind an anonymous function to the dragenter events of the droppable HTML element. In this event handler, we add the class: “dragEnter,” which changes the background color of that element. The reason for doing this is to tell the user: “If you want, you can drop the element that you are dragging.” But if you click the link above for the JSFiddle example, you’ll see that we have a problem. Although we add the dragEnter class when the user drags an element over the droppable element, we have not set a handler for when the user drags that element away; we can’t always assume that the user will drop the dragged element. So, we have to handle the case in which the user drags the element over the droppable element, but does not drop it, and then drags away.

Example # 2

The dragleave Event

Here is the JS fiddle link for Example # 2: http://jsfiddle.net/v9hawcof/1/

In Example # 2, we bind an anonymous function to the dragleave event of the droppable element. In that event handler, we simply remove the “dragEnter” class from the droppable element. If you click the jsFiddle link for Example # 2, you’ll see that the user experience is much better; when you drag the small blue box over the larger tan box, the droppable element turns green. So, if you choose not to drop the blue box, and drag it away, the droppable element turns back to tan.

Here is the working example for this article: http://examples.kevinchisholm.com/html5/drag-and-drop/part-ii.html

Here is the JavaScript for this article’s working example:
http://examples.kevinchisholm.com/html5/drag-and-drop/js/part-ii.js

Summary

It is hard to imagine a case in which you would not want to notify the user in some way of the various events that take place during a drag and drop operation. In this article, we focused on the case in which the user drags an element over a droppable one, but does not drop it, and then drags the draggable element away. By attaching event handlers to the dragenter and dragleave events, we have a window of opportunity in which the UI can be updated accordingly. How you prefer to handle the UX in this and similar cases is up to you, but it is an important area to consider.

Helpful Links for HTML5 Drag and Drop dragenter and dragleave Events

dragenter

https://developer.mozilla.org/en-US/docs/Web/Events/dragenter

dragleave

https://developer.mozilla.org/en-US/docs/Web/Events/dragleave

Getting Started with HTML5 Drag and Drop Part I: Introduction

HTML5

HTML5 LogoWhile there are plenty of JavaScript libraries that take the pain out of drag-and-drop, understanding how to implement this feature of HTML5 is not only possible, it’s easier than you may think.

So let’s face facts: drag and drop is something that most of us take for granted. Ever since the late ‘80s, we’ve been able to drag something on the screen and then drop it somewhere as a way of saying: “I want this.” or “ ….do something to this.” In recent years, that kind of functionality has become more and more commonplace in desktop browsers. It’s hard to believe, but drag-and-drop was originally supported in Microsoft Internet Explorer 5. Yep, the XMLHttpRequest object is not the only game-changing feature originally dreamed-up at Microsoft. Ironically, our good friend IE is the only major browser whose support is limited. IE 10 seems to be fairly in line with regard to the most critical features, but IE 9 and below lack features that make native drag and drop implementation frustrating.

Let’s close our eyes for a moment, and pretend we don’t need to support Microsoft Internet Explorer

Fortunately, the HTML5 specification includes a fairly robust API for drag and drop. Making HTML elements draggable and droppable is painless, and managing the related events is possible. The key to all of this is understanding the bare minimum needed in order to properly manage this functionality.

But isn’t everything “draggable” these days?

No, not quite. According to the HTML5 Drag and Drop specification, only images and anchor links are draggable by default (and the anchor must have an href attribute). So, if you want to drag any other kind of HTML element, there is a bit of work to do.

Wait, aren’t there a gazillion JavaScript libraries that make drag and drop a snap?

Yep, there sure are. So, if you merely want to download a library or jQuery plugin and simply “dragify” as needed, this article probably isn’t for you. But if you want to understand how native HTML5 drag and drop functionality works, read on!

HTML Base

In the code example above, we have the base HTML for the rest of the examples in this article. For brevity sake, I’ve stripped out all but the most essential areas of the markup so that you can focus on the technologies demonstrated in this article. When you view the page source for the final working example, you will see that there is more HTML, but it is for presentational purposes only.

Making an Element Draggable

In order to make an element draggable, you need only add a “draggable” attribute to that element, and set its value to “true”. This can be done by including the “draggable” attribute in the original html, or via JavaScript.

Example # 1A

In Example # 1A, we have made an HTML draggable by adding a “draggable” attribute to that element, and setting its value to “true”. While I could have simply added a “draggable” attribute to the HTML, I chose to do so using JavaScript in order to illustrate how much control you have over this.

The dragstart Event

While the code in Example # 1A is completely valid, unless the element in question is an image, or an anchor tag (with an href attribute), there is a bit more work to do. Providing a “draggable” attribute alone is not enough to make an element draggable. There is at minimum, a second step: provide an event handler for the dragstart Event.

The dataTransfer Object

The dataTransferobject is used to hold the data that is being dragged during a drag and drop operation.

Even in the most basic drag and drop implementation, the dataTransfer object is important. The reason for this is the core logic behind drag and drop: why would you want to drag something if you did not plan to eventually drop it? (At first I found this frustrating; I felt that the “draggable” attribute alone should suffice when you want to be able to drag an element. But the more I delved into the specification, the more the logic started to make sense.)

In order to drag an element, you’ll need to provide some data to the dataTransfer object. Ultimately, it does not matter what data you provide; you just need to use the setData method of the dataTransfer object to set some data. You must do this in the dragstart event. After your dragstart event handler returns, you cannot modify the dataTransfer object.

I bet I know what you are thinking now:

Aaaaaaaaaaaaahhhhhh, c’mon Kevin, another friggin’ object I gotta learn about? In the Intro you said something about this whole thing being “…easier than you may think” !!

I know. I kinda lied. But aren’t you glad you’re halfway across the river?

(Seriously, this is all no big deal. Considering how cool drag and drop is, learning about a few objects and methods is a small price to pay.)

The originalEvent Object

When thinking about drag and drop events, it becomes necessary to consider multiple event objects. For example, when you start dragging an element, it fires a “dragStart” event. But then consider the element that you might drop this element on. It fires a number of events as well. When handling any of these events, you will need access to the original event that fired, as a way to refer to the HTML element that was dragged. So, in your dragstart event handler, you’ll want to create a reference to the dragged HTML element itself. This way, in any of the events fired by the droppable element, you can obtain a reference to the element that was dragged (i.e. the element that you might want to drop onto the droppable element).

Example # 1B

In Example # 1B, we bind an event handler for the dragstart event of the HTML element that we plan to drag. That handler is the function: dragStartHandler. The dragStartHandler function takes the current event as its first argument. We then use the setData method of the originalEvent’s dataTransfer object. The originalEvent object is a property of the current event. In this case, the originalEvent is the dragStart event. When calling the setData method, we pass “Text” as the first argument. That simply tells the setData method what type of data we are about to set. The second argument is the ID attribute of the element that is being dragged. This is accomplished by referencing the target object of the event, which is the element that is being dragged, and then use the target object’s getAttribute method to retrieve the ID attribute of the target element.

Setting Up the Droppable Element

You don’t need to do anything special to allow one HTML element to be dragged over another. Once an element is properly “draggable,” you can drag it anywhere you like. But just like playing cards with Kenny Rogers, that gets old pretty quick. The next logical step in implementing HTML5 drag and drop is setting up the droppable element(s) so that you can handle the various events that fire during the process.

The dragover and drop Events

Example # 2

The dragover Event

In Example # 2, we have bound two event handlers to the droppable HTML element. The allowDragover function is bound to that element’s dragover event, and as you can see, it has little functionality: it simply prevents any default behavior that the browser might implement. Surprisingly, this is critical; the drop functionality will not work correctly without it. This is one event handler that you have to simply “set and forget.”

The drop Event

In Example # 2, we bind the dropHandler function to the drop event of the droppable element. This is where the real action should take place.

Example # 3

In Example # 3, we’ve added some functionality to the dropHandler function. First, we prevent any default behavior that the browser might have implemented. Next, we retrieve the ID of the HTML element that was dragged, leveraging the work that we did in the dragStartHandler function. The steps here are virtually the opposite of those taken to set the ID of the dragged element: we use the getData method of the originalEvent’s dataTransfer object, which itself is a property of the event object’s originalEvent property.

Next, we add the class “hasChild” to the element that received the drop. This is for presentational purposes only, but it does allow us to provide a better user experience by changing the appearance of the element that received the drop. Then we “move” the element simply by appending it to the droppable element, and then change the dragged element’s innerHTML to “Dropped”. Just like changing the appearance of the droppable element, this kind of approach usually makes for a better user experience.

Example # 4

In Example # 4, we have the full code for our working example.

Here is the working example for this article: http://examples.kevinchisholm.com/html5/drag-and-drop/part-i.html

Here is the JavaScript for this article’s working example: http://examples.kevinchisholm.com/html5/drag-and-drop/js/part-i.js

Summary

This article barely scratches the surface of what is possible with HTML5 Drag and Drop. My goal was to provide an introduction to the topic that focused on the bare essentials needed to get started. Below are links that provide much more in-depth information on the subject.

Helpful Links for HTML5 Drag and Drop

http://www.w3.org/TR/2011/WD-html5-20110113/dnd.html

http://html5demos.com/drag

http://www.webdesignerdepot.com/2013/08/how-to-use-html5s-drag-and-drop/

https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer

https://developer.mozilla.org/en-US/docs/Web/Events/dragstart

http://tutorials.jenkov.com/html5/drag-and-drop.html

Easy Text Input “Hints” with the HTML <datalist> Tag

HTML5

HTML5 Logo
Provide helpful “hint” functionality for your text-inputs with just a little bit of hidden markup: the <datalist> element!

One of the newer HTML5 elements that I hear very little about is the Datalist tag. I’m a bit surprised by this because the datalist element is super-easy to implement and quite helpful.

In a nutshell, this tag provides easy “hint-like” behavior for text-inputs.

Surely we’ve all seen how some websites will provide “hints” as you type in a text-box. One of the most common examples, of course, is Google search. As you type, a list of words that match your input appear in and below the text box.

Most noteworthy: the HTML5 Datalist tag is not supported in Internet Explorer version 9 and below, nor Safari. But I think most would agree that this feature is an enhancement. So, you could implement it in your page, and consider it a “nice to have” if the user’s browser supports it.

Needless to say, any real-time “wildcard” implementation of this concept requires not only AJAX but some pretty serious back-end engineering that will provide useful hints quickly.

But what if you have a fairly strong idea of what the user “might” type. For example, let’s say that you prompt the user to enter the name of a European country in a text box. While that text box may allow any input, the user is likely to enter words such as “Austria”, “Belgium” or “Czech Republic”. So, why not add a little sugar to your page and “suggest” some of those words as they type?

Example # 1

Here in Example # 1, we have a very simple HTML form. Below that is the HTML5 Datalist element. That list is bound to the form by setting the form’s “list” attribute to the ID of the datalist (i.e. “euroCountries”).

Yes, it really is that simple.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 1: http://jsfiddle.net/z99Jx/3/

How to Demo: When you view the JsFiddle.net link for Example # 1, you will see a text-input field in the output area. So, you just put your cursor in that input field and type any letter between “A” and “F”. And, of course, as you type, any country from the “euroCountries” list that has that letter in its name appears as a “hint”.

Oh my goodness… it really is that simple!

Example # 2

Now, here in Example # 2, there is code that you can run against this very web page. You may notice that in the upper-right-hand corner of this page, there is the text: “Search This Blog”. Below that is a text-input. If you type any letter between “A” and “F” right now, nothing happens.

Copy the code from Example # 2, paste it into your JavaScript console, and then execute it. Now, when you type any letter between “A” and “F”, any country from the “euroCountries” list that has that letter in its name appears as a “hint”.

Summary

In this article we learned about the new HTML5 Datalist tag. We also learned how this element can be used to provide “hints” for text input form elements. And finally, we learned how to bind that list to an input element, and set a list of options that will become the “hints”.

Helpful Links for the HTML5 Datalist tag

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist

http://caniuse.com/datalist

http://www.htmlgoodies.com/html5/markup/whats-new-in-html5-forms-the-datalist-control.html#fbid=NYUB4nW2C7h

http://www.quackit.com/html_5/tags/html_datalist_tag.cfm

http://webdesign.tutsplus.com/tutorials/introducing-the-html5-datalist-element–webdesign-9888

http://davidwalsh.name/datalist

HTML5 Offline Web Applications | Part III: The applicationCache JavaScript Object

HTML5

HTML5 LogoThe cache manifest file allows you to easily set up an HTML5 offline application. The applicationCache JavaScript Object allows you to monitor and act upon the events that take place as your app loads.

In Part I of this article, we learned the basics of creating HTML5 Offline Web Applications. In Part II, we learned about the “FALLBACK:” section, allowing us to provide default assets for files and pages that we do not want to be available offline. In this third part, we will learn about the events that fire during the process of loading your application.

The key to using JavaScript to interact with your HTML5 offline application is the global applicationCache object. This object has properties that we may want to know about and events that we may want to monitor.

It might make more sense to view the full working example first. This way the content of this article will make more sense. http://examples.kevinchisholm.com/html5/offline-web-apps/example-3/index.php

Example # 1

In Example # 1, we have our cache manifest file. The only thing here that is new is the file: cache-events.js. This is the JavaScript that will interact with the page.
text

File Structure

Image # 1

App File Structure

In Image # 1, we see the file structure of our application. I’ve consolidated the HEAD tag for each page into head.php, and cache-events.js is consolidated in footer.php.

Example # 2

In Example # 2 we have a simple function that takes a message as an argument and appends it to the DOM as an update. This will make more sense when you see the working example.

Example # 3

In Example # 3, we assign a function to the document’s “onreadystatechange” event. Whenever this event fires, we will add a list item element to the DOM, with the current value of the document’s readyState property. If that value happens to be “complete”, we add a message which lets us know whether or not we are online.

Example # 4

 

In Example # 4, we add an event listener to the applicationCache object. Each time an event fires on that object, we check to see if the event is named “updateready”. If so, we know that the cache manifest file has changed. The browser will update the UI the NEXT time the page is loaded. We inform the user that there is an update to the app, and ask if they want to reload. If they click “yes”, then we force a reload of the page, which will force the browser to use the newly cached assets.

Example # 5

 

In Example # 5, we add a series of event listeners to the applicationCache object. In each case, we call our logEvent() function. This function takes the event object as its first argument. In the logEvent() function, we examine the event object’s “type” property, and then call the updateUI function, in order to update the web page.

Image # 2

Ready State Events

In Image # 2, we see our JavaScript code in action. We see that the readyStateChange event fires twice. The first value of the readyState property is “interactive”, which means that the page is downloading. The second value is “complete”. At this point, we check our online status, which is “true”. If you turn your internet connection off and reload the page, that value would be “false”. We also see that two applicationCache events fire: “checking” and “noupdate”. This means that the browser checked to see if the cache manifest file changed, and in this case, there was no change.

Image # 3

Ready State Events

In Image # 3, we see that after the applicationCache event: “checking” fires, the “downloading” event fires. This is because the browser found that the cache manifest file has changed. Our JavaScript code prompts the user, asking if he or she wants to reload the page.
Image # 4

App Cache Error

Image # 5

App Cache Error in the JS Console

In Image # 4, we see that an error event has fired. Image # 5 shows the JavaScript console. We see that this error is expected because we are offline, so the cache manifest file cannot be checked.

Summary

In this article, we learned how to interact with HTML5 Offline Web Applications through JavaScript. We learned about the global applicationCache JavaScript object. We discussed the properties of this object that can be useful, and how to add event listeners so that we can monitor the activities of our offline web application.

Helpful Links for the HTML5 Application Cache JavaScript API

http://www.bennadel.com/blog/2029-Using-HTML5-Offline-Application-Cache-Events-In-Javascript.htm

http://motyar.blogspot.com/2011/09/handling-html5-application-cache-with.html

HTML5 Offline Web Applications | Part II: FALLBACK: Specifying Default Offline Assets

HTML5

HTML5 LogoSometimes there might be pages in your HTML5 Offline Web Application that should never be available offline, such as those requiring a login. The “FALLBACK:” section allows you to specify a default offline page that should be used in this case.

In Part I of this series “HTML5 Offline Web Applications | Part I: Getting Started”, we learned how the cache manifest file tells the browser which assets should be cached for offline use. One of the issues that we discussed was how each and every asset in the application must be defined in the “CACHE:” section of the cache manifest file. While this logic is easy to implement and works flawlessly, the rigidity of that approach can create problems. An issue you might run into is dynamic pages that cannot possibly work offline. A typical example is a page that requires a login, and then interacts with the server, such as a “Manage Your Account” page. This is the kind of functionality that you probably don’t want available offline because not only do you no longer have a connection to the server, but you lose the ability to verify credentials, etc…

The “FALLBACK:” section of the cache manifest file can solve this problem. In this section, we can specify a web page that should be used any time a non-cached resource is requested. In that page you can handle the scenario, for example letting the user know that in order to access the page they requested, they need to be connected to the internet.

Another area that can benefit from the “FALLBACK:” section is that of images. You can set up a default “offline” image that should be used whenever a certain image is requested. You can also say: “for any requests for resources in the /online-images/ folder, just show the image offline.jpg”

Example # 1

In Example # 1, we have the contents of our cache manifest file. The only changes since Part I of this article are the “FALLBACK:” and “NETWORK:” sections. The “FALLBACK:” section allows us to tell the browser: “hey, any time that someone requests file A, give them file B instead”. In this case we are using the file “kevin-offline.jpg” as the fallback. So when you are offline, you see the image of yours truly, with the word “OFFLINE” so elegantly scrawled across my face.

After the image entry, we have also specified that ANY file not listed in the “CACHE:” section, should be replaced by “offline.php”. The asterisk in the “NETWORK:” section, simply tells the browser that ALL files should be fetched online, but the entries in the “CACHE:” and “FALLBACK:” sections provide the overrides we need. I have found information on the “NETWORK:” section a bit confusing, as I think many others have as well. Suffice to say: If you want to use the “FALLBACK:” section, add a “NETWORK:” section with simply an asterisk as a single entry.

File Structure

Image # 1

Application File Structure

In Image # 1, we have the files that constitute our web application. What is new here are the pages “account.php” and “offline.php”, and the image file: “images/kevin-offline.jpg”. (I’ve also consolidated the page headers info header.php, but that was merely to eliminate repeated markup. It has nothing to do with the topic at hand.)

The “Manage Your Account” page.

Image # 2

The “Manage Your Account” page.

In Image # 2, we see the “Manage Your Account” page. Because this page requires a login, we don’t want it available offline.

Image # 3

The “Manage Your Account” page (offline version)

In Image # 3, we see the “Manage Your Account” page, but it looks different. Because we specified “offline.php” in our cache manifest file, that page is served up whenever a non-cached resource is requested. We did not list “account.php” in the “CACHE:” section of our cache manifest file, so when it is requested, “offline.php” is served up instead. So, when offline, if you request “account.php”, even though the browser address bar shows “account.php”, the browser shows you “offline.php”.

Image # 4

The Home Page (offline version)

In Image # 4, we see index.php in “offline” mode. Because we indicated that an offline request for “/images/kevin.jpg” should be replaced with “/images/kevin-offline.jpg”, we see the “fallback” image. Notice that the HTML5 logo in the lower-left-hand corner never changes. This is because we explicitly list it in the “CACHE:” section.

Here is a link to the full working example for this article: http://examples.kevinchisholm.com/html5/offline-web-apps/example-2/index.php

Open the above link in your browser, and then turn your internet connection off. Once you have turned your internet connection off, you can then click “About”, “Contact” or “Home”, and in each case the requested page will be shown, but you will see the “offline” version of the image of me.

Most importantly, note that without an internet connection, clicking “Account” results in the “You Are Offline” page. Once you go back online, the actual “Manage Your Account” page is shown.

Summary

In this article we learned about the “FALLBACK:” section of the cache manifest file. We learned how to specify “default” assets that should be served in the event that the asset requested is not in the cache.

Helpful Links for Cache Manifest “FALLBACK:” section

http://www.w3.org/TR/2011/WD-html5-20110525/offline.html#appcache

https://developer.mozilla.org/en-US/docs/HTML/Using_the_application_cache#Sections_in_a_cache_manifest_file.3A_CACHE.2C_NETWORK.2C_and_FALLBACK

http://en.wikipedia.org/wiki/Cache_manifest_in_HTML5#Fallback_section_with_the_header_FALLBACK

http://stackoverflow.com/questions/3281827/html5-cache-manifest-fallback-section-network

HTML5 Offline Web Applications | Part I: Getting Started

HTML5

HTML5 LogoIt’s surprisingly easy to create a web-based application that works offline. The key to getting started is understanding the cache manifest File.

While native apps have enjoyed great popularity in recent years, there is still a case to be made for web-based pages that behave like native applications. A critical element to any “app” behavior is the ability to operate offline. The HTML5 Offline Web applications specification is well supported and allows you to implement this “offline” behavior quite easily.

The Cache Manifest File

The critical component here is the cache manifest file, which is specified by the “manifest” attribute. By simply adding a manifest attribute to your page’s HTML element, a browser will recognize that web page as being cacheable. The browser will then download every file specified in the cache manifest file. It is important to note that if any file specified in the cache manifest is not available, the cache is considered invalid and the page will not be available offline. For this reason, it is critical to check each resource and make sure that the path specified in the cache manifest file is correct.

Location of the Cache Manifest File

The Cache Manifest File can be located anywhere on your web site. Entries in the file can be absolute or relative, but relative paths are in relation to the manifest file itself, not the web page. Also, it is not a good idea to specify resources that are in a folder that is a descendant of the folder that the manifest file is in. For example, you don’t want an entry such as this: ../../index.php. Make sure that any resources specified in the manifest file are in the same folder as that file, or a sub-folder.

Every time you change one of your assets, whether it CSS, JavaScript, HTML or even an image file, you need to make some kind of change to the cache manifest file.

Content type of the Cache Manifest File

Your cache manifest file must be served with the mime type: “text/cache-manifest”.

When Is the Cache Updated?

This is an area that can be a bit confusing at first. In a nutshell, the browser will never (ever) download newer versions of your assets unless the cache manifest file changes. This is one of the reasons why comments are so helpful. It’s not enough to simply “touch” the cache manifest file; the actual binary must change. So, if you simply change a comment, the browser will see the cache manifest file as being newer than the one it has previously cached. If you have a comment in your cache manifest file that has a version #, that is a simple way to make sure that the browser will see it as having been updated.

This is where developers might start pulling their hair out. Let’s say you are working on an HTML offline web application. You change a CSS file, and then upload it. But you keep refreshing the page and nothing is changing. So you upload the CSS file again, but still nothing is happening.

What Gives??

The only way that the browser will download the updated CSS file is if the cache manifest file changes. So, every time you change one of your assets, be it CSS, JavaScript, HTML or even an image file, you need to make some kind of change to the cache manifest file. When the browser sees that the cache manifest file has changed, it will download any files specified that have changed.

Example # 1

In Example # 1, we see that the HTML element in our page has a new attribute: “manifest”. The value of that attribute is the path to our cache manifest file. This value can be an absolute or relative path.

Example # 2

In Example # 2 we have the contents of our cache manifest file. The very first line: “CACHE MANIFEST” is required. The lines that start with the hash symbol (“#”) are a comment. Comments are completely ignored, but can be useful for reasons which will be discussed in part II.

Cache manifest files have four “sections”. In this example we see the “CACHE:” section. This tells the browser which files to explicitly cache. Although including a “manifest” attribute in your HTML tag tells the browser to cache the page, it is a good idea to specify all of the pages in your application in the “CACHE:” section. The reason for this is simple. If you do not list every page in the website, then users will need to browse directly to each one of those URLs in order for them to be cached locally. You won’t be able to simply visit “index.php” and then click “about.php”, because the browser will not have cached that file yet. If you specify every web page in your application, then they are all cached upon your first visit to any page in your application.

File Structure

Image # 1

Appication File Structure

In Image # 1, we have the files that constitute our web application. There is not too much going on here as this is a very simple example. The main point is that the cache manifest file must be in the highest folder. Any resources specified in the cache manifest file must be in the same folder as the cache manifest file or a sub-folder.

Here is a link to the full working example for this article: http://examples.kevinchisholm.com/html5/offline-web-apps/example-1/index.php

The best way to demonstrate the “offline” functionality of our working example is to open the above link in your browser, and then turn your internet connection off. Once you have turned your internet connection off, you can then click “About”, “Contact” or “Home”, and in each case the requested page will be shown. One reason that I specifically used PHP files is that as we know, PHP files will only work when served from a web server that supports PHP (i.e. you cannot copy a PHP file to your desktop and then view it in the browser). Yet once the pages are cached, you will notice that you are able to view each PHP file even with no internet connection. This provides a slightly more dramatic “proof of concept” because we know that you can save an HTML file to your desktop and then view it in a browser. So, when you see XXX.PHP in your browser’s address bar, yet you know you are completely offline, then you know you are working from the offline cache.

Summary

In this article we learned how to get started with HTML5 Offline Web Applications. We learned about the cache manifest file and why it is such a critical component. In this discussion, we also covered important details such as where the cache manifest file must reside, the syntax used, and how to force the browser to download newer versions of your assets.

Helpful Links for HTML5 Offline Web Applications

http://www.w3.org/TR/2011/WD-html5-20110525/offline.html

https://developer.mozilla.org/en-US/docs/HTML/Using_the_application_cache

http://diveintohtml5.info/offline.html

http://www.htmlgoodies.com/html5/tutorials/introduction-to-offline-web-applications-using-html5.html#fbid=cQxsRxCcZ5V

Making JSONP Calls from HTML5 Web Workers

HTML5

HTML5 LogoThe importScripts() function can be used to load any JavaScript file asynchronously from within a Web Worker, making JSONP a snap.

I just put the finishing touches on a photo gallery for a fairly large commercial web site. This template involved two dependencies: mustache.js and a jQuery carousel plugin, as well as three JSONP calls. All of this has to happen before anything can be displayed in the browser. Fun stuff.

I’ve spent plenty of time pressing F5 over and over to see how many milliseconds I could shave off the page load time. Since there is a bit of data crunching that also has to happen once all dependencies and JSONP calls have loaded, I started to think that this project would be a perfect candidate for some Web Worker love (of course with a safety net for older browsers). After some A/B testing, I could see that there was no real savings when implementing Web Workers. This is because the average 3-second load time was mostly due to the multiple asynchronous calls, not the data crunching. Since asynchronous calls are asynchronous, they don’t lock-up the browser, and it is only their latency that “keeps us waiting.”

That said, in the process of setting up my A/B testing, I had fun messing with Web Workers, and picked up a few new tricks, so I thought I’d post an article about making JSONP calls from a Web Worker.

If you’re not too familiar with HTML5 Web Workers, you might want to read these three posts; they offer an overview and a quick dive in to the topic:

Getting Started with HTML5 Web Workers – Part I
Getting Started with HTML5 Web Workers – Part II
Getting Started with HTML5 Web Workers – Part III

Before diving into the Web Worker code, I’ll just mention that the JSONP call we make responds pretty quickly, almost too quickly. As a result, it’s tough to demo our Web Worker, because there is no sense of “wait” (I spent over an hour making a pretty “loading” experience that merely flickers for a nanosecond because the JSONP call returns so quickly : – ). So I’ve implemented a “sleep” feature: we add &sleep=NUMBER to the query string. This way, we can make the JSONP call perform a little slowly, which helps to demonstrate our topic. Here is the PHP code that is added to the top of the JSONP file:

Ok, a little JSONP / Web Worker Action Please!

Example # 1

In Example # 1, we have the code for our Web Worker. First, there is the JSONP callback. In this callback, we fire off a message to the script that started the worker, and pass it the JSON data. Note that we need to use JSON.stringify() to convert that JSON data to a string. This is because we can only pass strings as messages to and from a Web Worker. But if we “stringify” a JSON object, that will do just fine.

Next we have set up an event listener. When the calling script sends a message to this Worker, the code inside of the event listener is executed. We create a random integer which is used to tell the JSON page to “sleep” for a few seconds, imitating a slow response. The other random # is used as a cache buster.

After that, we simply make the JSONP call. The importScripts() is oh-so-lovely and makes it super easy to import any JavaScript file.

Example # 2

In Example # 2, we have a simplified version of the click handler for the “Make JSONP Call” button. It simply sends a message to the Worker, which “starts” it.

Example # 3

In Example # 3, we instantiate the Worker() constructor, and then set up the event listener for that Worker. The code inside of this event listener will be executed when the Worker sends this script a message. I won’t drive you nuts by going through it line-by-line, but on a high level, we take the JSON data that the Worker sends us, and use JSON.parse() to turn it back into an object. Then, leveraging Mustache.js, we create an unordered list, using the JSON data that the Worker fetched for us.

Here is a link to the full working example for this article. Make sure you click the “Make JSONP Call” button: http://examples.kevinchisholm.com/javascript/web-workers/jsonp/

Summary

Again, the very act of making an asynchronous script call is not so strenuous for the browser. But I can imagine a case in which you need to fetch some JSON and then crunch the return data before passing it to the calling script. In such a case, the “crunching” is what could bog down the browser. And since data you pass to a Web Worker is essentially “copied,” your script could wind up using more memory than necessary, by getting the JSON data, passing a copy of it to the Web Worker, and then getting a copy back from the Worker once it has finished doing some work on the data. That is three copies of the same chunk of data!

By initiating your JSONP call from the Web Worker, you get the data, crunch the data, and then pass the data to the calling script. This removes one “copy” from the whole scenario. And, I’m thinking that after sending the data from the Worker to the calling script, you could probably delete the data inside of the Worker, freeing-memory. Although it will probably get cleaned up by garbage collection. More fun stuff to investigate.

Happy Web Worker-ing!

Kevin

Helpful Links for Web Workers

http://www.sitepoint.com/javascript-threading-html5-web-workers/

http://www.storminthecastle.com/2013/04/19/make-your-ui-more-responsive-with-html5-web-workers/

http://www.codediesel.com/javascript/introducing-html5-web-workers/

http://refcardz.dzone.com/refcardz/html5-web-workers

http://www.tutorialspoint.com/html5/html5_web_workers.htm

Getting Started with HTML5 Web Workers – Part III

HTML5

HTML5 LogoBy instantiating the Worker() constructor twice, we can see how more than one number-crunching task can be passed off to separate threads, once again leaving the browser responsive and completely available to the user.

In Part II of this article, we discovered the liberating effect of implementing a single Web Worker. We were able to pass our number crunching work off to the Worker, which ran in a separate thread. As a result, the browser remained responsive (e.g. we were able to resize the box while the numbers were being crunched). In this third and final part of the article, we will take things one step further by spawning two number-crunching threads, all the while continuing to keep the browser completely responsive.

Part III: Multiple Web Workers

Example # 1

In Example # 1, we have for the most part, replicated the approach taken in Part II of this article. The only difference here is that we have created two instances of the Worker() constructor (myWorkerOne and myWorkerTwo). We are using the same physical worker file (i.e. worker.js), so the argument passed to the Worker() constructor is the same in both cases. From there the steps are the same. We create our event listeners, and from each “Crunch some numbers” button, a message is sent to the appropriate Worker instance.

Click here to see the full working demo for Part III of this article: http://examples.kevinchisholm.com/javascript/web-workers/basic/example-3.php

When you clicked both of the “Crunch some numbers” buttons, a separate number-crunching task was passed off to a Worker in a new thread. You can see that the Ajax loader gif spins with no problem, and you are able to resize the boxes as much as you wish.

Click here to compare the examples from all three of the parts of this article: http://examples.kevinchisholm.com/javascript/web-workers/basic/example-1.php?menu

Summary

In this article, we demonstrated how multiple Workers can be used simultaneously. Just as in the example from Part II of this article, we proved that while the Worker is crunching numbers, the browser is completely responsive and available to the user.

The examples in all three parts of this article were very simple and meant only to introduce the topic of Web Workers. There is a great deal more to talk about with regard to Web Workers and I do plan to do so here in this blog in the coming weeks.

More Helpful Links for Implementing HTML5 Web Workers

http://www.htmlgoodies.com/html5/tutorials/introducing-html-5-web-workers-bringing-multi-threading-to-javascript.html#fbid=CwNX9_fBBqp

http://html5demos.com/worker

http://caniuse.com/#feat=webworkers

Getting Started with HTML5 Web Workers – Part II

HTML5

HTML5 LogoImplementing an HTML5 Web Worker is all about instantiating the Worker() constructor, creating event listeners, and posting messages between the Worker and the script that started it.

In Part I of this article, we made the case for Web Workers. We discussed the oh-so nasty concept of locking up the browser and how the single-threaded nature of JavaScript ensures that long-running scripts will send visitors away none-to-pleased. In this second part, we will use a Web Worker to pass off our “crunch” function to a separate thread, keeping the browser responsive and completely available to the user.

Part II : A Simple Web Worker

Example # 1

In Example # 1, we instantiate the Worker() constructor, passing it the name of a JavaScrpt file that has already been created and which contains the web-worker code. This file must be on the same domain as the page that calls it. In our case, it is in the exact same folder as the web page, so the path to the file is simply the name of the file: “worker.js”.

After instantiating the Worker() constructor, we add an event listener. This allows the worker file that we specified (i.e. worker.js) to send a message to the script that started the worker. The anonymous function that is the second argument of the addEventListener() method takes an event object as an argument (in this example, we call it “e;” you can name it anything you like). In this anonymous function, we remove a CSS class from the target DOM element, and then fill that element with whatever message the worker sent us. That message is contained in the “data” property of the event object (i.e. “e.data”).

Application Web Root
The Web Root – Web Page and Separate WebWorker File

Example # 2

In Example # 2, we have an abbreviated version of the click event handler for the “Crunch some numbers” button. What I wanted to illustrate is that we “start” the worker by sending it a message.

Example # 3

In Example # 3, we have the code for our Web Worker (i.e. the file worker.js). While all of the code in the script is evaluated and executed when we instantiate the Worker() constructor (just like any JavaScript file), the code inside of the self.addEventListener() call only executes when the worker receives a message. In this example, we set the variable “msg” equal to the “crunch()” function. Our crunch() function takes anywhere between one and ten seconds to return, simulating that nasty number-crunching behavior we have been talking about.

When crunch() does finally return, we post a message back to the script that started the worker. In this case, the message is the return value of crunch(): a string of markup that says “I’m done…” and tells us how long it took.

Click here for the full working demo of Example # 2:  http://examples.kevinchisholm.com/javascript/web-workers/basic/example-2.php

When you clicked the “Crunch some numbers” button, you were still able to resize the box, or do anything else you wished. The number crunching work was passed off to our Web Worker, which ran in a separate thread, which left the browser completely responsive and available to you.

This is a major improvement over the example in Part I of this article! In Part III, we will expand this demo to include a second number-crunching task, illustrating how we can spawn not only one, but multiple tasks to other threads using Web Workers.

Summary

In this article, we were introduced to the workings of Web Workers. We learned how to instantiate a Web Worker, start the Worker, post a message to it, and create an event listener so that we can respond when the Web Worker sends us a message, and access that message. We also learned how to setup an event listener in the Worker file, and post messages back to the script that started the worker.

Helpful Links for Implementing HTML5 Web Workers

https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers

http://www.html5rocks.com/en/tutorials/workers/basics/

Getting Started with HTML5 Web Workers – Part I

HTML5

HTML5 LogoHTML5 Web Workers significantly minimize the limitations imposed by JavaScript’s single-threaded nature, allowing you to keep the browser responsive.

HTML5 Web Workers significantly minimize the limitations imposed by JavaScript’s single-threaded nature, allowing you to keep the browser responsive.
When folks express their excitement about HTML5, the discussion is usually focused around features such as the AUDIO / VIDEO tags, Geolocation, or maybe improved semantics. These are all super cool, as are many other features that are part of (or associated with) the HTML5 specification. But, it often amazes me how little attention is given to Web Workers. In my opinion, the addition of Web Workers is a big deal.

This article will be presented in three parts:

Part I : Making the Case for Web Workers
Part II: A Simple Web Worker
Part III: Multiple Web Workers

Part I : Making the Case for Web Workers

JavaScript is a single-threaded technology. Only one thing can be done at a time.
Period. This is fine at first, but when JavaScript is doing any heavy-lifting, it can lock up the browser. Locking up the browser is bad, very bad. This is like a waiter serving your food late, and then spilling it on you. Regardless of how apologetic the waiter may be, you are not likely to tell your friends how great that restaurant is. As a web developer, all you need to do is lock up the browser once and you can be sure that the user is never (ever) going to tell their friends anything good about the page they were just viewing (and by association, the whole site gets a bad rap). They will not “like” it, tweet it, “plus-one” it, “pin” it, “dig” it or…. ok, you get the point: Don’t lock up the browser.

Number-crunching is probably the most challenging context. While all modern browsers have made great strides with regard to the speed of their JavaScript engines, heavy-duty calculations can still take time.. sometimes a few seconds. Unfortunately, a few seconds is out of the question. Many consider 100 milliseconds to be the limit; i.e. if a synchronous piece of code needs more than 100 milliseconds to return then that code probably needs some more attention.

HTML5 Web Workers allow you to execute JavaScript in a different thread than the one that the browser is running in. This is a big win. It means that in certain cases, your multi-second number-crunching code can be handed off to a Web Worker, and the browser can remain happy, peppy and bursting with love.

Did you notice the words: “…in certain cases” ? There are some limitations to how you can use Web Workers. It is far from a free-for-all. For example, you cannot access the Window, Document or Parent objects. Heavy DOM manipulation is out. At first glance, this may seem like a drawback. But as you can imagine, providing access to the DOM from more than one thread immediately complicates things in a way that is not good.

The key to leveraging the power of Web Workers is hinted at by its very name “worker.” Think of this feature as a calculator (or many calculators), that can be sent off to do some “work”, and then report back when done. I won’t go too crazy on the details here, there are many web-based resources that can provide an in-depth view of Web Workers. I’ve listed a few at the end of this article.

To make the case for Web Workers, let’s consider the following code example:

Example # 1

In Example # 1, we have a function that essentially “sleeps” for five seconds. If you run this code in your JavaScript console, it will lock up the browser for five seconds. Nasty business. We will use this code extensively throughout Parts I, II and III of this article. Every time you see this function referenced, just imagine that it is crunching some numbers (i.e where you see “I’m only sleeping”). The key point here is that a function that would need a few seconds to do some resource-intensive work, would behave in exactly the same way: it would lock up the browser.

Example # 2

in Example # 2, we have expanded the crunch() function so that it “sleeps” for a random number amount of time, up to five seconds. This makes the function feel a bit more “real world” in that the amount of time the function takes to “crunch” will vary a bit.

Click here to see a full working example of our “crunch” function in action: http://examples.kevinchisholm.com/javascript/web-workers/basic/example-1.php

In the example page, when you clicked “Crunch some numbers”, the browser locked up. If you tried to resize the box by clicking the “Re-Size Box” button, not only did nothing happen, but you probably got the “wait” cursor (this behavior varies from browser to browser). I intentionally used an Ajax loader gif to illustrate this: the gif’s animation is frozen during the numbers crunching. Once the “crunch” function has completed, it updates us with a message which tells us how long it took, and the browser is responsive again.

This is the “waiter spilling food on you” scenario. And it is not good.

In Part II, we will dive into Web Workers and learn how that technology can help us to pass off our number crunching work to a different thread, and keep the browser responsive at all times.

Summary

In this article we introduced the concept of Web Workers. We discussed the single-threaded nature of JavaScript and how it poses a challenge when it comes to resource-intensive work. We made our case with an example of a simple function that will render the browser unresponsive.

Helpful Links for HTML5 Web Workers

http://www.w3.org/TR/2009/WD-workers-20091029/

http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html

http://en.wikipedia.org/wiki/Web_worker

Super Easy HTML Video Support with LongTail Video’s JW Player and JavaScript

JavaScript

JavaScript LogoThis video player makes it simple to present video in your HTML page, and configure a wide array of options

While the new HTML5 video element brings much promise to the concept of full native browser support, it can still be a bit of an effort to provide cross-browser consistency. LongTail Video’s JW Player offers a way to implement some fall-back support and very cool customization. This little puppy does a great job of auto-detecting which method of playback is supported by the user’s device, and presents accordingly. There is support for both Flash and HTML5, skinning, plugins and a very robust API. At the bottom of this post are a few links that will more than get you started. I’ll simply highlight how easy it is to get JW Player up-and-running in your web page.

Example # 1

In example # 1, just to demonstrate that the most current version of JW Player works with a two-year-old version of jQuery, we pull in jQuery 1.4, and what would be a local copy of the jwplayer.js. With that done, we simply call the jwplayer() method, passing in the ID of the element within which we’d like the video player to run, and chain the return value to the JW Player .setup() method. We pass a configuration object to that method, and away we go! The only two requirements here are the jwplayer.js file and the player.swf file.

Example # 2

In example # 2, we added an “events” property to the configuration object, and to that property, we added an onReady method, which starts the video once the player is ready.

Example # 3

In example # 3 there is a code snippet that demonstrates the ability to remove a video from the page. JW Player takes care of all the DOM cleanup, including removing any bound events. You can add the video back in real-time by simply running the original function that appeared in the document.ready() method.

Summary

There is plenty (and I do mean plenty) to sink your teeth into here. I’ve only scratched the surface of the surface. If you are looking for a plugin that makes video support easy and offers tons of options, JW Player is a serious contender. Non-commercial use requires no payment and the commercial licence is very reasonable.

Helpful links forJW Player

http://www.longtailvideo.com/players/

http://www.longtailvideo.com/support/jw-player/jw-player-for-flash-v5/12540/javascript-api-reference

http://wordpress.org/extend/plugins/jw-player-plugin-for-wordpress/