Académique Documents
Professionnel Documents
Culture Documents
(
TUTORIALS INTERVIEW CHEAT SHEET SHOWCASE TEAM
TABLE OF CONTENTS
FOCUS ON PHONEGAP
BBC Olympics
by BBC & Adobe
NAVIGATE
GO BACK TO THE LIBRARY MOVE TO THE PREVIOUS ARTICLE DISPLAY THE TABLE OF CONTENTS VISUALLY BROWSE ALL THE ARTICLES
appliness
Many years ago, I was asked during a job interview at Google what changes I would make to the web in order to provide better experiences. At the top of my list was having some way to work with files other than the <input type=file> control. Thankfully, with HTML5 and related APIs, we now have far more options for working with files than ever before in the latest versions of desktop browsers.
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
- parse - read - consume
by Nicholas C. Zakas
2/8
<div id=your-files></div> <script> var target = document.getElementById(your-files); target.addEventListener(dragover, function(event) { event.preventDefault(); }, false); target.addEventListener(drop, function(event) { // cancel default actions event.preventDefault(); var i = 0, files = event.dataTransfer.files, len = files.length; for (; i < len; i++) { console.log(Filename: + files[i].name); console.log(Type: + files[i].type); console.log(Size: + files[i].size + bytes); } }, false); </script> The event.dataTransfer.files is another FileList object that you can access to get file information. The code is almost exactly the same as using the file form control and the File objects can be accessed in the same way.
3/8
}; xhr.open(post, /entrypoint, true); xhr.send(form); Once the FormData object is passed into send(), the proper HTTP headers are automatically set for you. You dont have to worry about setting the correct form encoding when using files, so the server gets to act as if a regular HTML form has been submitted, reading file data from the photo key and text data from the name key. This gives you the freedom to write processing code on the backend that can easily work with both traditional HTML forms and Ajax forms of this nature. And all of this works in the most recent version of every browser, including Internet Explorer 10.
console.log(Upload complete.);
4/8
};
reader.onerror = function(event) { console.error(File could not be read! Code + event.target.error.code); }; reader.readAsDataURL(file); This code simply inserts an image that was read from disk into a page. Since the data URI contains all of the image data, it can be passed directly into the src attribute of an image and displayed on the page. You could, alternately, load the image and draw it onto a <canvas> as well: var reader = new FileReader(); reader.onload = function(event) { var dataUri = event.target.result, context = document.getElementById(mycanvas).getContext(2d), img = new Image(); // wait until the image has been fully processed img.onload = function() { context.drawImage(img, 100, 100); }; img.src = dataUri;
};
reader.onerror = function(event) { console.error(File could not be read! Code + event.target.error.code); }; reader.readAsDataURL(file); This code loads the image data into a new Image object and then uses that to draw the image onto a canvas (specifying both the width and height as 100). Data URIs are generally used for this purpose, but can be used on any type of the file. The most common use case for reading a file into a data URI is to display the file contents on a web page immediately.
5/8
Reading ArrayBuffers
The ArrayBuffer type was first introduced as part of WebGL. An ArrayBuffer represents a finite number of bytes that may be used to store numbers of any size. The way data is read from an ArrayBuffer is by using a specific view, such as Int8Array, which treats the underlying bytes as a collection of 8-bit signed integers or Float32Array, which treats the underlying bytes as a collection of 32-bit floating point numbers. These are called typed arrays, which force you to work with a specific numeric type rather than containing any type of data (as with traditional arrays). You use an ArrayBuffer primarily when dealing with binary files, to have more fine-grained control over the data. Its beyond the scope of this post to explain all the ins and outs of ArrayBuffer, just realize that you can read a file into an ArrayBuffer pretty easily if you need it. You can pass an ArrayBuffer directly into an XHR objects send() method to send the raw data to the server (youll have to read this data from the request on the server to reconstruct the file), so long as your browser fully supports XMLHttpRequest Level 2 (most recent browsers, including Internet Explorer 10 and Opera 12).
Progress events
Progress events are becoming so common that theyre actually written up in a separate specification. These events are designed to generically indicate the progress of data transfers. Such transfers occur when requesting data from the server, but also when requesting data from disk, which is what FileReader does. There are six progress events: - loadstart indicates that the process of loading data has begun. This event always fires first. - progress fires multiple times as data is being loaded, giving access to intermediate data. - error fires when loading has failed. - abort fires when data loading has been canceled by calling abort() (available on both XMLHttpRequest and FileReader). - load fires only when all data has been successfully read. - loadend fires when the object has finished transferring data. Always fires and will always fire after error, abort, or load.
Tracking progress
When you want to track progress of a file reader, use the progress event. The event object for this event contains three properties to monitor the data being transferred: - lengthComputable a boolean indicating if the browser can determine the complete size of the data. - loaded the number of bytes that have been read already. - total the total number of bytes to be read. The intent of this data is to allow for progress bars to be generated using the information from the progress event. For example, you may be using an HTML5 <progress> element to monitor the progress of reading a file. You can tie the progress value to the actual data using code like this:
6/8
var reader = new FileReader(), progressNode = document.getElementById(my-progress); reader.onprogress = function(event) { if (event.lengthComputable) { progressNode.max = event.total; progressNode.value = event.loaded; } }; reader.onloadend = function(event) { var contents = event.target.result, error = event.target.error; if (error != null) { console.error(File could not be read! Code + error.code); } else { progressNode.max = 1; progressNode.value = 1; console.log(Contents: + contents); }
};
reader.readAsText(file); This is similar to the approach that Gmail uses for its drag and drop file upload implementation, where you see a progressbar immediately after dropping a file onto the email. That progressbar indicates how much of the files has been transferred to the server.
- FileError.ENCODING_ERR for encoding errors. - FileError.ABORT_ERR when abort() is called while there is no read in progress. You can test for the type of error either during the error event or during loadend: var reader = new FileReader(); reader.onloadend = function(event) { var contents = event.target.result, error = event.target.error; if (error != null) { switch (error.code) { case error.ENCODING_ERR: console.error(Encoding error!); break; case error.NOT_FOUND_ERR: console.error(File not found!); break; case error.NOT_READABLE_ERR: console.error(File could not be read!); break; case error.SECURITY_ERR: console.error(Security issue with file!); break; default: console.error(I have no idea whats wrong!);
};
reader.readAsText(file);
http://www.nczonline.net/
@slicknet
appliness
in the previous article, youve learned how to use files in the traditional way. You can upload files to the server and you can read file data from disk. These all represent the most common ways of dealing with files. However, there is a completely new way to deal with files that has the capacity to simplify some common tasks. This new way is to use object URLs.
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
- write - async - master
by Nicholas C. Zakas
EXAMPLE
So how would you display an image from disk without reading the data first? Suppose that youve given the user a way to select a file and now have a reference to it in a variable called file. You can then use the following: var URL = window.URL || window.webkitURL, imageUrl, image; if (URL) { imageUrl = URL.createObjectURL(file); image = document.createElement(img); image.onload = function() { URL.revokeObjectURL(imageUrl); }; image.src = imageUrl; document.body.appendChild(image);
This example creates a local URL variable that normalizes the browser implementations. Assuming that URL is supported, the code goes on to create an object URL directly from file and stores it in imageUrl. A new <img> element is created and given an onload event handler that revokes the object URL (more on that in a minute). Then, the src property is assigned to the object URL and the element is added to the page (you may want to use an already-existing image). Why revoke the object URL once the image is loaded? After the image is loaded, the URL is no longer needed unless you intend to reuse it with another element. In this example, the image is being loaded into a single element, and once the image has been completely loaded, the URL isnt serving any useful purpose. Thats the perfect time to free up any memory associated with it.
2/5
Slicing
One of the interesting things you can do with Blobs (and therefore, also Files) is to create a new Blob based on a subsection of another one. Since each Blob just represents pointers to data rather than the data itself, you can quickly create new Blob objects pointing to subparts of others. This is accomplished by using the slice() method. You may be familiar with slice() on strings and arrays, and the one for Blobs behaves in a similar manner. The method accepts three arguments: the offset of the starting byte, the offset of the ending byte, and an optional MIME type to apply to the Blob. If the MIME type isnt specified, the new Blob has the same MIME type as the original one. Browser support for slice() isnt yet ubiquitous, with Firefox supporting it via mozSlice() and webkitSlice() in Chrome (no other browsers support this method currently). Heres an example: function sliceBlob(blob, start, end, type) { type = type || blob.type; if (blob.mozSlice) { return blob.mozSlice(start, end, type); } else if (blob.webkitSlice) { return blob.webkitSlice(start, end type); } else { throw new Error(This doesnt work!); }
3/5
You can then use this function to, for example, split up a large file to upload it in chunks. Each new Blob being produced is independent from the original even though the data each references has an overlap. The engineers at Flickr use blob slicing to read the Exif information from photos that are uploaded rather than waiting to it on the server. When the file is selected, the Flickr upload page simultaneously starts to upload the file as well as read the Exif information from the photo. This allows them to give a preview of the extracted metadata in the page as the file is being uploaded.
4/5
CONCLUSION
This is the last part of the series on working with files in JavaScript. As I hope you learned, the File API is incredibly powerful and opens up entirely new ways of working with files in web applications. You no longer need to stick with plain file upload boxes when users need to upload files, and now that you can read the files in the client, that opens up all sorts of possibilities for client-side manipulation. You could resize an image thats too large before uploading (using FileReader and <canvas>); you could create a text editor that works purely in the browser; you could split up large files to upload piece by piece. The possibilities arent quite endless, but are pretty damn close.
http://www.nczonline.net/
@slicknet
appliness
As JavaScript moves further and further away from the playground programming language that it used to be, and is used more and more as the core for large-scale applications, managing the code starts to become extremely difficult. Splitting the code into multiple files helps with that, though it also adds more complexity in a different way. One way to fight this new complexity is with dependency management libraries, but which one is right for you?
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
- load - run - execute
by Joe Zimmerman
$script.js
This handy library was created by Dustin Diaz and Jacob Thornton and is hosted on Github. Thats where youll find the documentation on how to use it, but Ill still show it off a bit here to give you an idea of how it works. Ive actually already written an article about this library which happens to be the first post ever on this blog but its focus was quite different. First, well talk about the most basic usage: loading a script. $script(jquery.js); This loads jquery.js asynchronously onto the page. This is no more useful than just using a normal script tag though. Its slightly shorter, but since it is loaded asynchronously, the code right after this line will run before jquery.js is loaded. So, we also give it a callback function that runs after jquery.js is loaded. $script(jquery.js, function() { // do stuff with jQuery. }); Now, once jquery.js is loaded and executed, well be sure that we can access the objects and functions that it defines. There is so much more you can do with $script.js including named dependencies but this gives you the gist of how to use it. With this, weve successfully defined a dependency and assured the dependency would be loaded and executed before we tried to use it. Using something like this allows us to only need to use 2 script tags in our HTML (one to load $script.js and one to load the main application). The rest of the scripts that we depend on can be managed with $script.js.
requirejs
RequireJS is a much larger project, with a Github project and a site of its own. Youll find the documentation for RequireJS at that second link, but if you want to read some history and a more thorough introduction to RequireJS you can read this article on Adobe Developer Connection. RequireJS can be use almost exactly like $script.js to load plain JavaScript files, but its so much more powerful than that. You can define modules, and then load those module dependencies in without exposing them globally, so that every bit of your code can be safe from 3rd party scripts. Take a look. First well just define a module that can pulled in as a dependency. // This is just an object literal define({ name: Joe Zim, gender: male }); // Heres a constructor so you can create // new objects, rather than just the one // literal object define(function() { var Person = function( name, gender ) { this.name = name; this.gender = gender; };
2/4
} );
return Person;
You can see two different types of modules there. The first one is just defined as an object literal, which will be what is returned to the dependent script, as youll see later. The second example has a function, which will be run immediately when the module is loaded as a dependency and the value that is returned from that function will be the value that is given to the dependent script. Now well create a module that is dependent on the module we just defined. Well assume that the module above is saved as person.js. Heres how we define another module that is dependent on the module we just made, plus another module that was created behind the scenes. define( [ person, list ], function( Person, List ) { var personList = new List( new Person(Joe Zim, male); ); } ); return personList;
We define the module exactly as we did before, except this time we send in an array as the first parameter. The array lists strings of file names (sans the .js) of modules to fetch. Then, when those modules are fully loaded, they are sent in as parameters to the function for the new module you are defining. As stated above, this localizes the modules so they are not accessible globally. Now well write a bit of code that is dependent on the latest module and the person module, but isnt creating a new module. Well assume that the latest created module is saved as default-person-list.js. require( [ default-person-list, person ], function( list, Person ) { var chuck = new Person( Chuck Norris, male ); list.addItem( chuck ); list.forEach( function( item ) { alert(item.name); } ); } ); This is almost exactly the same as creating a module that is dependent on another module except for a couple important things: 1. We no longer use the define function; instead we use require (finally we know where the name of the library comes from!). 2. Theres no need to return anything from the function. Since this is not being defined as a module, it is just run as is and therefore has no need to return anything. Thats the gist of RequireJS, but theres one more thing thats pretty important to note about RequireJS. It comes with a build tool that will look through all of the modules and other JavaScript files and concatenate and minify them so that even though you spent all that time create separate files, it wont become a performance problem.
3/4
http://www.joezimjs.com/
@joezimjs
appliness
Raymond camden has been working on a cool proof of concept. The idea is to reproduce the behavior of the facebook news feed and add some features.
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
by Raymond Camden
So lets start off with a first draft of the application. In this version, Ill run a scheduled process every few seconds or so, get new content (which will just be random), and simply prepend it to my div. Heres this version: <html> <head> <title></title> <script type=text/javascript src=http://ajax.googleapis.com/ajax/libs/ jquery/1/jquery.min.js></script> <script type=text/javascript src=support.js></script> <script type=text/javascript src=handlebars.js></script> <script> var template; var streamDiv; $(document).ready(function() { var source = $(#itemTemplate).html(); template = Handlebars.compile(source); streamDiv = $(#stream); //set up an interval to ask for new data window.setInterval(checkData, 4000);
Handlebars.registerHelper(dateFormat, function(dt) { return (dt.getMonth()+1) + / + dt.getDate() + / + dt.getFullYear() + + (dt.getHours()+1) + :+dt.getMinutes(); }); }); function checkData() { console.log(running checkData); //for now, create 0-3 fake items var newDataSize = Math.floor(Math.random()*3); if(newDataSize === 0) return; var data = []; for(var i=0;i<newDataSize;i++) { //create a simple news item: title, author, date var item = {}; item.created = new Date(); item.author = generateFakeName(); item.title = generateFakeTitle(); data.push(item); } console.dir(data); data.forEach(function(itm) { var html = template(itm); streamDiv.prepend(html) }); } </script>
2/9
<script id=itemTemplate type=text/x-handlebars-template> <div class=item> <h2>{{title}}</h2> By: {{author}}<br/> Posted: {{dateFormat created}}<br/> </div> </script> <style> #stream { width: 400px; } .item { border: solid black 1px; margin-bottom: 15px; background-color: #e0e0e0; } </style> </head> <body> <h2>Stream</h2> <div id=stream></div> </body> </html> Im assuming most of this will be pretty basic for Appliness readers. Im making use of Handlebars for my display. You can see the template generation first in the document ready block. I set an interval of 4 seconds for generating new content. My checkData function handles getting the new data. I select a random number of items from 0 to 3. If we have any number over 0, I generate fake news items for each. Finally - we take each new item item and prepend it to a div. This is as about as simple as it gets.
3/9
animations
For my next iteration, I decided to work on the animation. jQuery has a nice animation method called slideDown. Given hidden content, you can use this to slowly reveal the content over a duration. Here is the modified version for the updated display code: data.forEach(function(itm) { var html = template(itm); var domitem = $(html); domitem.hide(); streamDiv.prepend(domitem); domitem.slideDown(slow); }); This was pretty simple, but has a small bug in it. In any iteration of checkData, you may have multiple new items added to the stream. With the code above, each one has its own slide effect. When you have 2 items you get a venetian blinds type of effect. While this was wrong, I thought it was kinda cool too:
I figured that I could fix this by applying the hide/slideDown to a wrapper for all of the new content in any given run of checkData. I modified the code to create a new div around my N news items and then applied the animation to that: data.forEach(function(itm) { html += template(itm); }); html += </div>; var domitem = $(html).hide(); streamDiv.prepend(domitem); domitem.slideDown(slow);
4/9
Handlebars.registerHelper(dateFormat, function(dt) { return (dt.getMonth()+1) + / + dt.getDate() + / + dt.getFullYear() + + (dt.getHours()+1) + :+dt.getMinutes(); }); $(#stream).on(mouseover,.item, function() { console.log(hiding); hiding=true; //console.log($(this).position().top); }); $(#stream).on(mouseout,.item, function() { console.log(UNhiding,html); hiding=false; addToStream(html); }); }); function checkData() { console.log(running checkData); //for now, create 0-3 fake items var newDataSize = Math.floor(Math.random()*3); if(newDataSize === 0) return; var data = []; for(var i=0;i<newDataSize;i++) { //create a simple news item: title, author, date var item = {}; item.created = new Date(); item.author = generateFakeName(); item.title = generateFakeTitle(); data.push(item); } console.log(data.length + added); data.forEach(function(itm) { html += template(itm); }); if(!hiding) { addToStream(html); } } function addToStream(addedHTML) { addedHTML = <div>+addedHTML+</div>; var domitem = $(addedHTML).hide(); streamDiv.prepend(domitem); domitem.slideDown(slow); html=;
6/9
} </script> <script id=itemTemplate type=text/x-handlebars-template> <div class=item> <h2>{{title}}</h2> By: {{author}}<br/> Posted: {{dateFormat created}}<br/> </div> </script> <style> #stream { width: 400px; } .item { border: solid black 1px; margin-bottom: 15px; background-color: #e0e0e0; padding: 5px; } </style> </head> <body> <h2>Stream</h2> <div id=stream></div> </body> </html> I pasted the entire template since this one has changes in multiple areas. First - note the mouseover/ mouseout event handlers. When we mouseover, I update a global variable to indicate we should hide updates. When we mouseout, we flip that and run a new method, addToStream. Note that html is now a global variable. If you scroll down to checkData, you can see now that we check the hiding status before we display anything. Because we have 2 places that need to display html (remember the mouseout event above), I abstracted it out into its own method. addToStream simply renders out the items and clears the global html variable.
scrolling
Ok... still with me? For the final modification, I wanted to make it so that if you had scrolled down (in theory to view a news item), the main stream div would not update. This is rather easy if you listen for scroll event on the window object. However - I also wanted to make this rule have less priority then the mouseover rule. Since I only had one global variable (hiding), I needed another flag just for when I had mouseovered content. This code block has the relevant changes.
7/9
$(document).ready(function() { var source = $(#itemTemplate).html(); template = Handlebars.compile(source); streamDiv = $(#stream); //set up an interval to ask for new data hb = window.setInterval(checkData, 4000);
Handlebars.registerHelper(dateFormat, function(dt) { return (dt.getMonth()+1) + / + dt.getDate() + / + dt.getFullYear() + + (dt.getHours()+1) + :+dt.getMinutes(); }); $(#stream).on(mouseover,.item, function() { console.log(hiding); hiding=true; mouseOvered=true; //console.log($(this).position().top); }); $(#stream).on(mouseout,.item, function() { console.log(UNhiding,html); hiding=false; mouseOvered=false; addToStream(html); }); $(window).on(scroll,function() { //Only care if not mouseOvered if(mouseOvered) return; var scroll = $(window).scrollTop(); if(scroll > 0) hiding = true; else { hiding = false; if(html != ) addToStream(html); } }); }); Looking at the mouse events, you can see the new variable being set, mouseOvered. Below them you can see the new handler for scroll events.
8/9
Im not terribly sure how smart this is, but it seems to work ok in my testing:
appliness
JavaScript is a curious language. Its easy to write, but difficult to master. By the end of this article, hopefully, youll transform your spaghetti code into a five-course meal, full of readable, maintainable yumminess!
Why is it So Tough?
The thing to remember, above all else when writing JS code, is that its a dynamic language. This means there are a lot of ways to do things. You dont have to deal with strongly typed classes, or some of the more complex features from languages, like C# and Java. This is both a blessing and a curse. The hardness of JavaScript is clearly evident when considering the following image:
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
- cache queries
- comment - organize
by Jonathan Creamer
The teeny tiny book on the left is Douglas Crockfords MUST READ book, JavaScript: The Good Parts. Towering next to it, on the right, is, JavaScript The Definitive Guide, by David Flanagan. While both of these books are excellent reads, The Good Parts illustrates that, although JavaScript has a LOT of stuff in it, the good parts can be summed up in a considerably shorter read. So, if youre looking for a good, quick read, go with The Good Parts and read it a few times! You can read an article on the history of JavaScript here, but the gist of it is that Brandon Eich, in 1995, was hired by Netscape to design a language. What he his, naturally, led to a lot of came up with was the loosely typed language that we sleepless nights for web de- know as JavaScript. Over the years, it became standardized as ECMAscript, but, throughout all the browsvelopers. er wars, the various browsers implemented these features differently. This, naturally, lead to a lot of sleepless nights for web developers. This problem, when combined with the fact that JavaScript was considered to be most applicable for manipulating images and performing quick bits of validation, led JavaScript to, incorrectly, be viewed as a terrible language.
Its time to fix that! While, yes, there are plenty of bad things about JavaScript, when used properly, it can be a fantastic language and its dynamic nature will grow on you!
Making it Better
Namespaces One of the downfalls of how JavaScript is implemented is that it operates on top of a global object. In the case of browsers, this will wind up being the window object. So, anytime that code like this is present on a page function doStuff(){ alert(I am doing stuff); } function doMoreStuff(){ var images = document.images.length; console.log(There are + images + on this page); } doStuff(); doMoreStuff(); The functions doStuff and the doMoreStuff functions are immediately available to the global window object.
2/8
This means that if anyone comes along and attempts to write a function, which is also called, doStuff, there will be a conflict! All script tags are basically taking the code within them, and running it against the window in the order that they are referenced in the HTML. As a result, the second person to implement doStuff will overwrite the first doStuff.
A common technique for eliminating this problem is to take advantage of either self-executing anonymous functions, or namespaces. The object-oriented folks reading this are likely already familiar with the concept of a namespace, but the basic idea is to group functions into different areas for re-usability. var NS = NS || {}; // If NS is not defined, make it equal to an empty object NS.Utils = NS.Utils || {}; NS.Models = NS.Models || {}; NS.Views = NS.Views || {}; This will prevent pollution of the global namespace, and will aid in readability for your application. Now, you simply define functions in their respective namespace. A commonly defined namespace is app, which manages the rest of the application.
esign patterns are reusable solutions to commonly occurring problems in software design.
There are lots, and, when used correctly, they can greatly impact your applications maintainabilty. Addy wrote a great JavaScript design patterns book, called Essential Design Patterns. Absolutely give it a read! Another commonly used pattern is the Revealing Module Pattern. NS.App = (function () { // Initialize the application var init = function () { NS.Utils.log(Application initialized...); }; // Return the public facing methods for the App return { init: init }; }()); NS.App.init(); Above, an App function is defined within the NS object. Inside, a function variable for init is defined, and returned as an anonymous object literal. Notice that, at the end, theres that extra set of parenthesis: } ());. This forces the NS.App function to automatically execute and return. Now, you can call NS.App. init() to initialize your app. The anonymous function above is a best practice in JavaScript, and is referred to as a Self-Executing Anonymous Function. Because functions in JavaScript have their own scope i.e. variables defined inside of functions are not available outside of them this makes anonymous functions useful in multiple ways. // Wrap your code in a SEAF (function (global) {
3/8
var somethingPrivate = you cant get to me!; global.somethingPublic = but you can however get to me!; }(window)); console.log(window.somethingPublic); // This works... console.log(somethingPrivate); // Error In this example, because this function is automatically executed, you can pass the window in to the executing part }(window));, and it will be made available as global inside of the anonymous funtion. This practice limits the global variables on the window object, and will assist in preventing naming collisions. Now, you can start using SEAFs in other areas of your application to make the code feel more modular. This allows for your code to be re-usable, and promotes good separation of concerns. Heres an example of a potential use for these ideas. (function ($) { var welcomeMessage = Welcome to this application! NS.Views.WelcomeScreen = function () { this.welcome = $(#welcome); }; NS.Views.WelcomeScreen.prototype = { showWelcome: function () { this.welcome.html(welcomeMessage) .show(); } }; }(jQuery)); $(function () { NS.App.init(); }); // Modify the App.init above var init = function () { NS.Utils.log(Application initialized...); this.welcome = new NS.Views.WelcomeScreen(); this.welcome.showWelcome(); }; So, above, there are a few different things going on. Firstly, jQuery is passed as an argument to the anonymous function. This ensures that the $ is actually jQuery inside of the anonymous function. Next, theres a private variable, called welcomeMessage, and a function is assigned to NS.Views.WelcomeScreen. Inside this function, this.welcome is assigned to a jQuery DOM selector. This caches the selector inside the welcomeScreen, so that jQuery doesnt have to query the DOM for it more than once.
4/8
OM queries can be memor y intensive, so please ensure that you cache them as much as possible.
Next, we wrap the App init within $(function(){});, which is the same thing as doing $(document).ready(). Finally, we add some code to the app initializer. This keeps your code nice and separated, and will be considerably easy to come back to and modify at a later day. More maintainability!
observer Pattern
Another excellent pattern is the Observer Pattern sometimes referred to as Pubsub. Pubsub essentially allows us to subscribe to DOM events, such as click and mouseover. On one hand, were listening to these events, and, on the other, something is publishing those events for example, when the browser publishes (or announces) that someone clicked on a particular element. There are many libraries for pubsub, as its a short bit of code. Perform a quick Google search, and thousands of choices will make themselves available. One solid choice is AmplifyJSs implementation. // A data model for retrieving news. NS.Models.News = (function () { var newsUrl = /news/ // Retrieve the news var getNews = function () { $.ajax({ url: newsUrl type: get, success: newsRetrieved }); }; var newsRetrieved = function (news) { // Publish the retrieval of the news amplify.publish(news-retrieved, news); }; return { getNews: getNews }; }()); This code defines a model to fetch news from some kind of service. Once the news has been retrieved with AJAX, the newsRetrieved method fires, passing through the retrieved news to Amplify, and is published on the news-retrieved topic. (function () { // Create a news views. NS.Views.News = function () { this.news = $(#news); // Subscribe to the news retrieval event. amplify.subscribe(news-retrieved, $.proxy(this.showNews));
};
5/8
}; }());
This code above is a view for displaying the retrieved news. In the News constructor, Amplify subscribes to the news-retrieved topic. When that topic is published, the showNews function is fired, accordingly. Then, the news is appended to the DOM. // Modify this the App.init above var init = function () { NS.Utils.log(Application initialized...); this.welcome = new NS.Views.WelcomeScreen(); this.welcome.showWelcome(); this.news = new NS.Views.News(); // Go get the news! NS.Models.News.getNews();
};
Again, modify the init function from the app to add the news retrieval and youre done! Now, there are separate pieces of the application, each of which is responsible for a single action. This is known as the Single Responsibility Principle.
6/8
Grunt Google Closure JSMin YUI Compressor These tools will strip out whitespace, remove comments, and combine all specified files into one. This reduces the file sizes and HTTP requests for the application. Even better, this means that you can keep all of your files separated during development, but combined for production.
AMD
Asynchronous Module Definition is a different way of writing JavaScript code; it divides all code into separate modules. AMD creates a standard pattern for writing these modules to load in code asynchronously.
Using script tags blocks the page, as it loads until the DOM is ready. Therefore, using something like AMD will allow the DOM to continue loading, while the scripts are also still loading. Essentially, each module is divided into its own file, and then theres one file that kicks off the process. The most popular implementation of AMD is RequireJS. // main.js require([libs/jquery,app.js], function ($, app) { $(function () { app.init(); }); }); // app.js define([libs/jquery, views/home], function ($, home) { home.showWelcome(); }); // home.js define([libs/jquery], function ($) { var home = function () { this.home = $(#home); }; home.prototype.showWelcome = function () { this.home.html(Welcome!); }; }); return new home();
7/8
In the code snippet above, there is a main.js file, which is where the process begins. The first argument to the require function is an array of dependencies. These dependencies are a list of files that are required for app.js. As they finish loading, whatever the module returns is passed as an argument to the function callback on the right.
Then, there is app.js, which requires jQuery, as well as a view. Next, the view, home.js, only requires jQuery. It has a home function within it, and returns an instance of itself. In your application, these modules are all stored within separate files, making your application very maintainable.
Conclusion
Keeping your applications maintainable is extremely important for development. It reduces bugs, and makes the process of fixing ones that you do find easier.
http://jcreamerlive.com/
@jcreamer898
appliness
If you have a content site like a blog, for example, integrating social sharing buttons have become a necessary evil. Dont get me wrong, I enjoy Twitter as much as the next guy (I tolerate Facebook while grudgingly participate in LinkedIn and some others) but cluttering your page with a variety of buttons for sharing is usually an eye-sore but necessary if you want people to find and share your content. However, the lack of visual appeal is only one of the potential problems with these buttons. The other is that they all rely on third-party scripts being loaded that can potentially block the loading of your content.
There are a number of articles that document the problem with loading third-party scripts, and Ill cover that topic very briefly here. Thankfully though, if you want to quickly and easily add social sharing buttons to your content without blocking your content, David Bushell has created a small JavaScript library called Socialite.js that will help you do this. This article will show you how to use Socialite.js to load in the common social networks that are built-in and how to load a pre-existing extension to expand the network support.
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
- socialize
by Brian Rinaldi
Integrating Socialite.js
One potential solution to this issue is to use asynchronous loading of third party scripts and this is exactly what Socialite.js by David Bushell is designed to help you do very simply. Essentially, Socialite.js is a micro-framework designed specifically for asynchronously loading and rendering third-party social sharing scripts. It comes with support for pretty much all of the most popular social networks and, while it also comes with a number of pre-built extensions, it is designed to be extended should you require additional networks. Lets look at a quick example which I have implemented on my blog. Previously, I had social sharing buttons for Twitter, Facebook and Google Plus all manually added via the instructions for each on their respective sites. While many social networks have been improving their implementations, this still usually requires adding a script to load either in my document head or body as well as potentially some additional JavaScript code to customize and render the button. In order to replace this, first I need to load the Socialite.js script. Ive downloaded the minified version and imported it into my site immediately prior to my end tag. I should note at this point that Socialite.js does depend upon jQuery so you will also need to have loaded that prior. <script src=js/socialite.min.js></script> Next I need to initialize Socialite.js when my document loads. <script> $(document).ready(function() { Socialite.load($(#social)); }); </script> This is pretty much the most basic implementation available with Socialite.js. It does allow a good deal of settings and other customizations should you require them but for a basic share button from the most common networks this may not be necessary (and wasnt for me). One of the useful features of Socialite, which I dont cover here, is that you can load these buttons on events other than document ready, including on mouse events like hover, for example. You will notice though that I am passing in a jQuery object for the DOM element with the ID of social. For Socialite, this is the context within which it will search for elements to replace with the proper sharing buttons. You will want to limit the context to prevent Socialite from having to search too much of your page, nevermind the entire document.
2/4
So lets take a look at my social DOM element to see how to implement Twitter.
<ul class=social> <li><a href=http://twitter.com/share class=socialite twittershare data-url=http://remotesynthesis.com data-count=horizontal datavia=remotesynth rel=nofollow target=_blank><span class=vhidden>Share son Twitter</span></a></li> </ul> In my case as in the examples provided, the DOM element is a unordered list that is styled to hide the bullets and text within the links. Essentially, this is just a container for Socialite to fill, but the link also provides quite a bit of data and properties that I want to pass to Twitter. The way Socialite works, these properties will generally be identical to the properties youd have used on your script. So, in this case my Twitter link without Socialite would have been identical apart from the class (and would have had some additional JavaScript beneath the link as you can see in the instructions on Twitters site). Socialite does require the data- prefix on properties but this appears to also be a standard convention of many, though not all, social sharing scripts. While this means that youll have to reference the documentation for each share button separately and the properties wont necessarily match between Twitter and, say, Facebook, it also makes it extremely easy to convert existing buttons to use Socialite. Heres how I added Google Plus... <li><a href=https://plus.google.com/share?url=http://remotesynthesis.com class=socialite googleplus-one data-size=small annotation=bubble datahref=http://remotesynthesis.com/post.cfm/best-of-javascript-html5-css3-weekof-june-4-2012 rel=nofollow target=_blank><span class=vhidden>Share on Google+</span></a></li> ...and Facebook... <li><a href=http://www.facebook.com/sharer.php?u=http://www.remotesynthesis. com class=socialite facebook-like data-href=http://remotesynthesis.com/ post.cfm/best-of-javascript-html5-css3-week-of-june-4-2012 data-send=false data-layout=button_count data-width=60 data-show-faces=false dataaction=like><span class=vhidden>Share on Facebook</span></a></li> ...and finally LinkedIn. <li><a href=http://www.linkedin.com/shareArticle?mini=true&amp;u rl=http://remotesynthesis.com class=socialite linkedin-share dataurl=http://remotesynthesis.com/post.cfm/best-of-javascript-html5-css3-weekof-june-4-2012 data-counter=right rel=nofollow target=_blank><span class=vhidden>Share on LinkedIn</span></a></li> Support for all of these social networks are built-in by default into the standard Socialite.js script. However, there are obviously plenty of other social networks you may wish to support that are, thankfully, supported via pre-built extensions. Lets discuss using those.
Buffer GitHub Hacker News Pinterest Spotify VK.com I decided to add in the Hacker News button just for kicks (Ive never managed many links or votes on HN but maybe this will help after all). The first thing I did was obviously download and import the extension (you may, in the long run, want to combine extensions into the minified Socialite.js to reduce HTTP requests): <script src=js/extensions/socialite.hackernews.js></script> Now, one thing to be aware of with Socialite extensions is that it isnt always obvious what, if any, properties you need to provide, even after looking into the extension code. However, I initially just included another list item to be replaced for Hacker News like this: <li><a href=http://www.hackernews.com/shareArticle class=socialite hack ernews-share><span class=vhidden>Share on Hacker News</span></a></li> This didnt work but looking into my HTML via Chrome Developer Tools, I was able to discern that the URL it was using for the generated iFame was http://hnbutton.appspot.com/button which, if you open it, will show that a title and URL properties are required. Knowing that we must use the data- prefix for Socialite, the correct code to include this button would be: <li><a href=http://www.hackernews.com/shareArticle class=socialite hack ernews-share data-title=Best of JavaScript, HTML5 & CSS3 - Week of June 11, 2012 data-url=http://remotesynthesis.com/post.cfm/best-of-javascript-ht ml5-css3-week-of-june-11-2012><span class=vhidden>Share on Hacker News</ span></a></li> Once you know what the necessary or available properties are, its really easy.
Going Forward
My goal is to follow up this article with one covering how to build your own Socialite extensions for additional social networks. While this isnt well documented at the moment, David has been very responsive and I hope to contribute to the project both by creating an extension for this tutorial as well as documenting how to create one.
ABOUT THIS ARTICLE
Brian Rinaldi is a Content and Community Manager for the Adobe Developer Center team, where he helps drive content strategy for HTML5 and JavaScript developer content. Brian blogs regularly at http://remotesynthesis.com and is an unreformed twitter addict.
http://remotesynthesis.com/
@remotesynth
appliness
JEREMY KHAN workS for YouTube, loves open source, and writes lots of JavaScript... BUT HE DOESNt LIKE THIS LANGUAGE. DISCOVER WHY AND HOW HE HANDLES IT.
INTRODUCTION
I dont like JavaScript. I write an enormous amount of JavaScript in fact I write it almost exclusively but I dont really like it as a language. I dont want to write a giant screed as to why I dont like the language, but suffice it to say that it lacks some really basic features (like default parameters), and its lack of clearly defined rules (semicolons, whitespace) create lots of headaches. Something that has helped me keep JavaScript manageable and even fun is the coding styles I have developed. I create a lot of rules for myself that result in extremely readable and descriptive code. This equates to lots of boring style constructs and boilerplate comments that add absolutely no features to what Im writing, but go a long way to keep the code obvious and explicit. I write JavaScript as though it were C, at least to some extent. Why do I create this extra work for myself? Because reading code sucks. It will always suck, whether you are reading your own code or somebody elses. Especially when it comes to my open source projects, I really, really want people to read and contribute to the code I write. It is absolutely worth it to take extra time to trivially polish code so that fellow humans can easily dive right in. Additionally, I read my code many more times than I write it, so I want to have mercy on my future self by writing painfully obvious and straightforward code.
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
- optimize - be old
- readable
by Jeremy Khan
Much of my style is rooted in the Google JavaScript Style Guide. This is largely due to the fact that I need to follow this style guide in my day job. However, I have fallen in love with the strictness of the Google Way, and have adapted it for my own open source projects. For said open source projects, I dont follow Google 100% because, well, I have my own opinions on clean code. Its needless to go over every minutiae of my style, but I think there a few basic rules that go a long way in keeping large amounts of code sane and manageable.
2/6
3/6
Well, I really like the new keyword. When I see new in code, I read it as make a new instance of the following. Heres an example of why I like this clarity: var kitty = Cat(); This is simple enough, but kitty could be anything. Cat could be giving us a number, for all we know. I prefer this: var kitty = new Cat(); You may prefer to just capitalize your constructors, but I feel that using new helps to clearly communicate that a function is actually a constructor.
4/6
Compile-time defines
Compilers are totally awesome. Generally speaking, you shouldnt deploy production code unless its been compiled with tools such as the Google Closure Compiler or UglifyJS. For my open source projects, I prefer UglifyJS. I actually get better compression with Closure Compiler, but UglifyJS is easier to develop with. UglifyJS also has a few really awesome features. One that Ive fallen in love with is code preprocessing with compile-time defines. This feature is a throwback from the C world, and probably other compiled languages that are older than I. In any case, using defines lets you tailor your compiled binaries to fulfill various requirements. For example, you can use defines to tailor a build for mobile platforms that need different code than desktop platforms.
Im using defines for Rekapis testing hooks. There are some methods that I want to expose for my unit tests, but I dont want to expose them in the compiled code that gets sent to users. Its just wasted bandwidth and CPU cycles to parse it. Heres how I set it up: // At the beginning of the library if (typeof KAPI_DEBUG === undefined) { var KAPI_DEBUG = true; } // Later on in the code if (KAPI_DEBUG) { Kapi._private = { calculateLoopPosition: calculateLoopPosition ,updateToCurrentMillisecond: updateToCurrentMillisecond ,tick: tick ,determineCurrentLoopIteration: determineCurrentLoopIteration ,calculateTimeSinceStart: calculateTimeSinceStart ,isAnimationComplete: isAnimationComplete ,updatePlayState: updatePlayState }; } Kapi._private has references to a bunch of methods that will never be used publicly, but need to be exposed for testing. KAPI_DEBUG is a global variable (eeek!), but is only present in the source code, not the compiled binary. This is thanks to my build.js script: var var var var uglifyJS = require(uglify-js); jsp = uglifyJS.parser; pro = uglifyJS.uglify; ast = jsp.parse( _fs.readFileSync(_distFileName, utf-8) );
ast = pro.ast_mangle(ast, { defines: { KAPI_DEBUG: [name, false] } }); This tells UglifyJS to set KAPI_DEBUG to false when it is compiled. Because my debugging code is wrapped in conditional that tests the boolean value of KAPI_DEBUG, it is marked as unreachable code and not included in the binary. Perfect!
5/6
Something to note: At the time of this writing, this feature is poorly documented, but a Pull Request is pending.
I write code that is boring, because boring code is readable code. I would contend that readability generally has more impact on the success of a project than micro-optimizations and stylistic experimentation. If that means writing like a C coder in the 80s, then so be it.
http://jeremyckahn.github.com/
@jeremyckahn
appliness
Ive made it clear that Im a huge fan of LocalStorage. While sitting in the Houston airport for many hours this week, I decided to whip up a little example that demonstrates one of the practical uses for this feature.
Building templates
I built a simple Ajax-based search page and then added LocalStorage as a way to remember your previous searches. This isnt anything special, but I think its another good example of the feature. Lets begin by taking a look at the application before any use of LocalStorage.
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
- pictures - art
- save search
by Raymond Camden
The application makes use of Bootstrap, jQuery, and Handlebars, but for now, lets just focus on the JavaScript and the template: <script> $(document).ready(function() { var source = $(#artResultsTemplate).html(); var template = Handlebars.compile(source); $(#searchButton).on(click, function(e) { e.preventDefault(); var search = $.trim($(#search).val()); if(search === ) return; console.log(search for +search); $.get(service.cfc?method=searchArt, {term:search}, function(res,code) { var html = template({results:res}); $(#results).html(html); },JSON); }); }); </script> <script id=artResultsTemplate type=text/x-handlebars-template> <h1>Results</h1> {{#if results}} <ul class=thumbnails> {{#each results}} <li class=span3> <div class=thumbnail> <img src={{image}} width=260 height=180 title={{name}}> <div class=caption> <h5>{{name}}</h5> <p>{{description}}</p> <p>Created by {{artist}} and selling for ${{price}}</p> </div> </div> </li> {{/each}} </ul> {{else}} <p> Sorry, no results. </p> {{/if}} </script> You can see that I begin by compiling my Handlebars template (this is used for the results), and then I define my click handler for the search button. All the handler does is grab the search string, pass it to a ColdFusion service that hits the database, and then passes the results to my Handlebars template.
2/4
Beautiful - and the code is rather simple. You can test this yourself. Id recommend searching for oil, moon, paint, and beer:
Ok, now lets talk about the next version. The updated version will use LocalStorage to remember your last five searches. I decided on five mostly because it just felt right. I thought ten might be a bit much. To store the last five values, Ill use an array. You cant store complex variables in LocalStorage, but you can easily serialize them with JSON. So for example: var pastSearches = []; if(localStorage[pastSearches]) { pastSearches = JSON.parse(localStorage[pastSearches]); }
That isnt too complex, is it? Storing the value isnt too hard either. I do a check to see if the value exists in the array, and if not, put it in the front and pop one off the end if the array is too big. if(pastSearches.indexOf(search) == -1) { pastSearches.unshift(search); if(pastSearches.length > 5) { pastSearches.pop(); } localStorage[pastSearches] = JSON.stringify(pastSearches); }
3/4
All thats left then is to simply write out the past searches and listen for click events on them. function drawPastSearches() { if(pastSearches.length) { var html = pastSearchesTemplate({search:pastSearches}); $(#pastSearches).html(html); } } $(document).on(click, .pastSearchLink, function(e) { e.preventDefault(); var search = $(this).text(); doSearch(search); }); And voila - I can now remember your last five searches and provide an easy way for you to quickly rerun them. The code samples above are only the most important bits. I encourage you to View Source on the updated version for the complete example.
appliness
Andy demonstrates how to use Adobe edge to create animated components in your applications.
Edge animations
Youve probably heard of Adobe Edge, a timeline-based tool for creating interactive and animated HTML content. Edge enables you to easily create interactive experiences that rely only on HTML, CSS, and JavaScript. If youve used other Adobe Creative Suite tools, such as Flash Professional, Premiere, or After Effects, then Edge will probably look quite familiar. You have a timeline and controls to edit your content. Edge has been used to animated the cover of the July issue of Appliness with Eric Meyer.
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
- animate - extract
- modules
by Andrew Trice
Currently, the normal use case for Edge is creating interactive experiences that are loaded when the page loads. You can chain animation compositions in sequence, but they have to be in the same wrapper HTML file. This works great for a number of use cases, but one thing I wanted to do is create an Edge animation and use that as a component that is arbitrarily added to the HTML DOM at any point in time. My findings: It can be done, although with a few gotchas. Using Edge animations as components inside of a larger HTML experience isnt the primary use case which Edge was designed for. However this use case is being evaluated and may end up in Edge at a later date. If that happens, this process will become much easier. If youre wondering What was I thinking?, Ill try to explain while discussing the process of building HTML-based apps, I had the thought: Wouldnt it be cool to have a really elaborate loading animation while loading data from the server? We could use Edge to build the animation! As a proof of concept, I created a very basic application that loads two separate Edge animations on demand. Before I go into too much detail on what I built, lets take a look at the running example. This example has two buttons, one shows a car animation, one shows an airplane animation. Its pretty basic and straightforward:
The first thing that I did was create two simple Edge animations which you can view in this sample: cars and planes. All images used in these animations were obtained from thenounproject.com.
2/5
files, so that I can keep everything separate. First, I created the basic shell for the application. It is more or less an empty HTML structure, where all content is added at runtime: <body> <div id=contentHost ></div> </body> nside of the contentHost div, all UI is added to the HTML DOM upon request. Basically, when the user clicks a button, the Edge animation is added to the DOM, and then the animation begins.
In order to get this working, I had to change a few things in the generated Edge output: 1. in the *_edge.js file, I changed the DOM Ready event handler to use an arbitrary event that I can control. By default, Edge uses the jQuery $(window).ready() event to start the animation. Since I am adding this to an existing HTML DOM, the $(window).ready() event is not applicable. Instead, I changed this to use a custom animationReady event: $(window).bind( animationReady, function() { Edge.launchComposition(compId); }); 2. In the *_edgePreload.js file, I added a reference to the onDocLoaded function so that I can manually invoke it later, once the Edge animation has been added to the DOM, since again, this wont rely on the load event. //added this so it can be invoked later window.onDocLoaded = onDocLoaded; I also changed the aLoader object to reference the appropriate JavaScript files, since I changed their location in the directory structure: aLoader = [ { load: templates/animation_planes/edge_includes/jquery-1.7.1.min.js}, { load: templates/animation_planes/edge_includes/jquery.easing.1.3.js}, { load: templates/animation_planes/edge_includes/edge.0.1.6.min.js}, {test: !hasJSON, yep:templates/animation_planes/edge_includes/json2_min. js}, { load: templates/animation_planes/planes_animation_edge.js}, { load: templates/animation_planes/planes_animation_edgeActions.js}]; 3. Finally, I created the Mustache.js template, which will be used to generate the HTML DOM elements that will be appended to the existing DOM. In this there is a wrapper DIV, some HTML content including a button and some text (the animation number is dynamic for the templating), the styles, a Stage div, and Edge preload JavaScript files necessary for the animation. </pre> <div id=animationContainer> <button id=removeAnimation>Restore Default View</button> Animation {{animationCount}}
3/5
<script charset=utf-8 type=text/javascript src=templates/ animation_planes/planes_animation_edgePreload.js></script></div> <pre> 4. Next, lets look at how this is actually injected into the DOM. I created a setupAnimationView() function to inject the animations into the DOM. This function is used by both animations. The first thing that it does is remove any existing DOM content and dereference the AdobeEdge variables in memory. Since Edge wasnt originally designed for asynchronously loading animations, I found it to be easiest to just wipe-out Edge and reload it for every animation. The unfortunate side effect is that you can only have one Edge animation on screen at any given point in time. Next, the setupAnimationView() function generates the HTML DOM elements and event listeners and adds them to the DOM. Finally, I created an edgeDetectionFunction, which checks to see if Edge is loaded. If not, it loads the Edge runtime. The edgeDetectionFunction() then checks if the Edge animation is sufficiently loaded. If the animation definition is not loaded, it just waits and tries again. If the animation definition is loaded, it dispatches the animationReady event (discussed in step 1) to invoke the actual animation. function setupAnimationView( template ) { $(#contentHost).empty(); window.AdobeEdge = undefined; AdobeEdge = undefined; animationCount++; var viewModel = {animationCount:animationCount}; var html = Mustache.to_html(template, viewModel) $(#contentHost).append( html ); $(#removeAnimation).click( setupDefaultView ); //detect if edge is loaded yet var edgeDetectionFunction = function() { if ( AdobeEdge && AdobeEdge.compositions != undefined) { var hasComposition = false; if ( AdobeEdge.compositions ) { //loop to see if the composition is actually loaded for ( var key in AdobeEdge.compositionDefns ) { hasComposition = true; break; } } if ( hasComposition ) { setTimeout( function(){ $(window).trigger( animationReady ); }, } return;
100 );
} edgeDetectionFunction();
4/5
Since I am using Edge in a manner for which it was not initially designed, there are a few gotchas that I ran into: - You cant have multiple instances of the same Edge animation in a single HTML DOM at least, not easily. Each Edge animation is assigned a unique ID. This ID is referenced in the HTML structure and the *_edge.js, *_edgeActions.js, and *_edgePreload.js files. You would need to assign a unique ID to each instance, and make sure everything is referenced consistently. - It will be very tricky asynchronously add more than one Edge animation at the same time. The shortcut that I used to get these to render was to wipe away the Edge variables in JS and reload them this would cause some issues with more than one animation.
If the capability to have Edge animations as components gets built into Edge (which I hope it does!), then you will not have to go through all of these steps, and it will be much easier. Ill be sure to share more if this feature develops.
A COOL ANIMATION BUILT WITH ADOBE EDGE (TAP TO PLAY THE ANIMATION)
TAP TO PLAY
appliness
Why do you write HTML using the <h1> tag and the <p> tag? Why not just use <div> and <span> tags for everything? Why use any specific HTML tags at all? The reason is that <p> and <h1> tags convey extra information about the content. They say this is a paragraph and this is a heading at the first level, respectively. This is semantic HTML, or HTML for which the author makes every effort to ensure that the markup organizes and structures the content. To some degree, all web developers practice it. This article will explain semantic HTML, and explain why you should go deeper into it.
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
- think
- write - understand
by Terry Ryan
Semantic HTML is HTML in which: - Text is wrapped in elements that reflect the content. For example: - A paragraph is contained in a <p> element. - A sequential list is contained in an <ol> element. - A large block of text quoted from another source is contained in a <blockquote> element. - HTML elements are not used for a purpose other than their semantic purpose. For example: - <h1> contains headings; it is not for making text bigger. - <blockquote> contains a long quote; it is not for indenting text. - An empty paragraph element ( <p></p> ) is not used to skip lines. - Text contains no stylistic information directly. For example: - No use of format tags such as <font> or <center> . - No reference to colors or location in classes or IDs. The purpose of all this is so consumers of your code, be it people, browsers, or screen readers can consume the content and easily parse it, both objectively for machines and subjectively for people.
think search engines favor semantic HTML, and Googles input into HTML5 suggests that they do. However, search engines closely guard their algorithms, and have to allow for the fact that extremely relevant content may be placed in nonsemantic HTML. Repurposing Semantic HTML takes advantage of the fact that a news item will always be a news item, and an archive will always be an archive, no matter where they are positioned on the page. However, a rightbar wont always be on the right side. Additionally if you are syndicating your content via an RSS feed and including HTML in it, the less markup the better. However, most sites and blogs dont syndicate their content straight from prepared HTML. Theyre usually built separately, and the syndication format is handled to make sure that other consumers understand the content. Developer comprehension You may have noticed a theme in the arguments for semantic HTML covered thus far. All of these sound like good reasons to use semantic HTML, but none of them individually really seals the deal for me. Perhaps all of them add up to be enough to justify it to you. If so, thats great. But I contend that there is a really good reason to write semantic HTML today. Coding is communication, both to a computer (which is the easy part) and to other developers. Semantic HTML is easier for humans to understand than nonsemantic HTML. A div element with a class of r1c4 is not as easy to figure out as one named pullquote. By using semantic HTML, you help other developers and HTML authors understand what your code is doing. Its important to note that there is a great deal of subjectivity in this space. In his article About HTML semantics and front-end architecture, Nicholas Gallagher makes the case that classes and IDs cant be nonsemantic because semantics are about meaning, and anything you put in a class or ID has meaning. His logic is sound, but in my opinion this is not the best way of looking at things. Semantics are not binary. You cannot be entirely semantic, nor can you be completely nonsemantic. Semantic is a continuum quality. Web content exists on a continuum between completely nonsemantic and completely semantic, because those poles are unreachable. With that in mind, as you increase the ease with which consumers of web content can understand what all the pieces of your web content mean, you move the content across the continuum from nonsemantic to semantic.
3/5
There are many more elements, which are detailed at the W3Cs list of differences between HTML4 and HTML5. The point of these is to create a more standard way of marking up content. The more consistent the markup, the easier it is for both humans and devices to consume it.
whichElement.com WhichElement.com is a site that I started to discuss proper semantics for content. For example if you are looking for a way to mark up a calendar semantically, whichElement.com has the answer for you.
4/5
To learn more about semantics in HTML5: HMTL5 Doctor HTML5 Doctor is a resource to help developers use HTML5 as it stands in the ever-involving present. The site has lots of great information on the semantic usage of HTML5 elements.
Adobe Developer Connection Stephanie (Sullivan) Rewis has a great series of articles, Understanding HTML5 semantics, that can help you jump into using new semantic HTML elements. - Part 1: New elements - Part 2: Document structure and global attributes - Part 3: Changed and absent elements
http://www.terrenceryan.com/
@tpryan
appliness
Over the weekend I decided to write up a quick example of form validation in jQuery Mobile. Obviously there are many ways you can accomplish this and I just wanted to take my own little spin with it. Heres what I came up with and Id love to hear how other jQuery Mobile users are doing validation.
Lets start off with a real simple jQM site. It will have a home page with links to two sub pages. My form will be on the second page. To be honest, I could have just built a one page site, but I wanted something with a trivial bit of navigation to it so it felt just a bit more realistic. I wont bore you with all the code (you can view source on the demo yourself), but here is our simple form: <!DOCTYPE html> <html> <head> <meta charset=utf-8> <meta name=viewport content=width=device-width, initial-scale=1> <title>Register Page</title> <link rel=stylesheet href=http://code.jquery.com/mobile/1.1.1/jquery. mobile-1.1.1.min.css /> <script src=http://code.jquery.com/jquery1.7.1.min.js></script> <script src=http://code.jquery.com/mobile/1.1.1/ jquery.mobile-1.1.1.min.js></script>
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
- design
- code - validate
by Ray Camden
</head> <body> <div data-role=page> <div data-role=header> <a href=index.html data-rel=back>Home</a> <h1>Register Page</h1> </div> <div data-role=content>
<form action=process.cfm method=post> <fieldset data-role=fieldcontain> <label for=username>Username:</label> <input type=text name=username id=username> </fieldset> <fieldset data-role=fieldcontain> <label for=password>Password:</label> <input type=password name=password id=password> </fieldset> <fieldset data-role=fieldcontain> <label for=password2>Confirm Password:</label> <input type=password name=password2 id=password2> </fieldset> <fieldset data-role=fieldcontain> <label for=email>Email:</label> <input type=email name=email id=email> </fieldset> <fieldset data-role=fieldcontain> <label for=favcolor>Favorite Color:</label> <select id=favcolor name=favcolor> <option>Select One</option> <option>Green</option> <option>Red</option> <option>Blue</option> <option>Yellow</option> </select> </fieldset> <fieldset data-role=fieldcontain> <label for=hometown>Home Town:</label> <input type=text name=hometown id=hometown> </fieldset> <input type=submit value=Register>
2/8
</form>
</div>
<div data-role=footer> <h4>Footer content</h4> </div> </div> </body> </html> The form consists of 6 fields: username, password, the password confirmation, your favorite color, and your home town. The validation rules should be: Everything but the home town is required. Username, password, and the confirmation must be 5 characters minimum. The password confirmation must match the password. Pretty simple, right? Without any validation at all, you can take this for a spin here: Round 1 And if you dont want to bother with that - a quick screen shot (which I generated from Adobe Shadow thank you very much):
3/8
Ok, so lets talk validation. It would certainly be cool if we could just use HTML5 form validation, right? I mean, look at the mobile browser support for Canvas:
Thats a hell of a lot of green. So obviously - if there is that much support for canvas, which is only mildly useful in practical matters - surely there is even higher support for form validation, something we probably all use every single day.
*sigh* Ok, so moving on from that, lets talk options. Obviously we can roll our own JavaScript. It isnt terribly difficult to do so. But I thought it might be nice try the jQuery Validation plugin. Ive blogged on it before (see links at the bottom) and I liked how simple it made things. I thought Id give it a shot here and see how it ran. The plugin provides two main ways of adding validation to a form. You can either add items to a class attribute of your form or supply a list of validation rules when initializing the plugin. Personally, I dont know which I prefer. I wish the plugin made use of a data-attribute instead of a class, but I like seeing my rules in the HTML. I went with that approach but just keep in mind you have the other option as well. Heres the updated HTML for the register page (just the form bits): <form action=process.cfm method=post id=registerForm> <fieldset data-role=fieldcontain> <label for=username>Username:</label> <input type=text name=username id=username class=required min length=5> </fieldset> <fieldset data-role=fieldcontain> <label for=password>Password:</label> <input type=password name=password id=password class=required minlength=5> </fieldset> <fieldset data-role=fieldcontain>
4/8
<label for=password2>Confirm Password:</label> <input type=password name=password2 id=password2 class=required minlength=5> </fieldset> <fieldset data-role=fieldcontain> <label for=email>Email:</label> <input type=email name=email id=email class=required email min length=5> </fieldset> <fieldset data-role=fieldcontain> <label for=favcolor>Favorite Color:</label> <select id=favcolor name=favcolor class=required> <option value=>Select One</option> <option value=green>Green</option> <option value=red>Red</option> <option value=blue>Blue</option> <option value=yellow>Yellow</option> </select> </fieldset> <fieldset data-role=fieldcontain> <label for=hometown>Home Town:</label> <input type=text name=hometown id=hometown> </fieldset> <input type=submit value=Register>
</form> Notice the addition of class=required to my fields requiring validation. Also note the minlength of the first three fields. This is - pretty much - all it takes. The one big obvious piece missing is the confirmation must match password field but that can be handled in a custom rule. I also had to initialize the validation but thats one line of code: $(#registerForm).validate();
5/8
First, the errors dont really stand out and second - note the error for the drop down. Its actually inside the custom jQM drop down field. Not good. Lets tackle the design first. By default, the validation plugin will use an error class for displaying errors. That means it is pretty trivial to make it look a bit nicer: label.error { float: left; color: red; padding-top: .5em; vertical-align: top; font-weight:bold }
6/8
Nice. About halfway there. You can demo this version here: Round 2 So what about the weird drop down behavior? We can use another feature of the plugin to handle that. You can use a property, errorPlacement, that allows you to dynamically determine where errors should be written out. While were at it, we can also go ahead and create the custom rule for password matching. $(document).on(pageshow, #registerPage, function() { $.validator.addMethod(passmatch, function(value) { return value == $(#password).val(); }, Confirmation password must match.); $(#registerForm).validate({ errorPlacement: function(error, element) { if (element.attr(name) === favcolor) { error.insertAfter($(element).parent()); } else { error.insertAfter(element); } } }); });
7/8
To be honest, the use of .parent() there was a bit of a guess, but it worked on first try. In case youre curious, to add the custom validation to the second password field I just had to add the name to the class list: class=required passmatch.
You can demo this version here: Round 3 So, what do you think? Id like to work on this a bit more. On the iPad, the errors are left aligned under the labels, which is kinda cool, but I could also see them being aligned with the fields instead. On desktop it is way off but I kinda figure that is an edge case and not something Id have to worry about. As always, comments and critiques are welcome.
ABOUT THIS ARTICLE Meet Raymond Camden. He is a 38 year old married father of three living in beautiful Lafayette, Louisiana. Ray is a developer evangelist for Adobe where his primary technical focus is ColdFusion, jQuery, Flex, AIR and the mobile space.] http://raymondcamden.com/
@cfjedimaster
PA U L IRISH
Im a front end developer who cares a lot about the web and wants to help developers make awesome shit.
1/11
Hi Paul. Thank you for setting aside some time to work with us. We are very excited to have you as the featured developer for this issue of Appliness. Can you tell us a little about yourself?
Sure thing. Thank you very much! So, Im a developer advocate on the Google Chrome team, and that means Im focused on making developers productive in building highly developed web apps. Ive worked on a number of open projects like HTML5 Boilerplate, Modernizr, jQuery, HTML5 Please, CSS3please, movethewebforward.org. Right now Im focused on developer tooling, productivity, and my new project Yeoman. On the whole, Id say Im a front end developer who cares a lot about the web, wants it to win, and wants to help developers make awesome shit.
Your resume states you teach web developers how to make the web more awesome. What are some important tips for making awesome web applications?
One of the things I think is really important is that you focus on the user experience. We, as front end developers, have a responsibility to craft a user interface that is really fantastic to work with and play with for users. While what were doing is getting more and more sophisticated as time goes on, the amount of things we have to learn is increasing. So its very easy to get wrapped up in the architecture of building. Ive seen a lot of developers get over-focused on what the application architecture is, and lose track of what the actual end user experience is supposed to be. I think its key to prioritize what we can do to improve the user experience in our application. The other thing Id focus on is performance. Having a web app thats snappy and responds very quickly makes for a happy experience. 60fps is a mantra Ive internalizing and a goal thats always keeping me optimizing for a great UX. One tool in particular to help you out with this is the Timelines Frames View inside the Chrome Developer Tools. Ive recorded two videos about how to put it to use very well. Really, the key here in being performance is first: measuring, second: identifying bottlenecks, and third: smoothing them out.
60 fps is a mantra. The keys for performance: measuring, identifying bottlenecks, smoothing them out
2/11
Can you tell us a little about what you get to do in your role with Google?
My focus is on the developer experience of making web apps and making developers productive. So the projects that Im focused on these days are Yeoman and Chrome Developer Tools. In Yeoman, we are crafting an open source stack of tool software that makes it easy to develop a compelling web app. Its a modern iterative development environment where you can take advantage of pre-processors and enjoy recompilation, live reloading, and a very rich build system. So the end product is as optimal and as fast as possible for our users. And with Chrome Developer Tools, my focus is really on making sure that developers know all the functionalities within the tools so when a problem comes up, they know exactly how best to use the tools to their advantage. There is a lot of power hidden in there. At the same time Im talking to the engineering team to prioritize developers needs and features.
What strides has Google made with Chrome in making it a legitimate browser for developers to target web applications with the latest HTML5 technologies?
This is extremely important for Chrome. Chrome is all about making a first class experience for web applications. Im going to start with the devtools, and then focus on new features in the platform. First, client side storage in devtools; we have support for for session storage, local storage, application cache, indexeddb, and now even shadow DOM. Chrome, as a browser, has some of the highest scores in things like caniuse.com and html5test.com. I think this is in part because of the release cycle. It gets the new features that engineers are working on into developers hands, to let developers play with it. The quickest youll get Chromes new feature is daily, the slowest--once every six weeks. Thats amazingly fast compared to the state of things 3 years ago. Its this kind of quick feedback system where we can offer the newest developer feature for whoever is building new apps. Another thing that Google Chrome focuses on is having fantastic performance. And part of it is that Chrome uses world test cases to drive performance. A good example here is Dromaeo. Dromaeo was put together by John Resig awhile ago; it collects together a few different test suites, including ones from jQuery, which tests DOM performance. The jQuery Project was using these to see if it could get faster, release by release. But now we use it inside WebKit to determine if WebKit can get faster when it manipulates dom. If youve paid attention to performance maxims, youll know a huge one is that touching DOM is very slow. You can play in plain JavaScript all you want, but one touch to the DOM nukes your performance in very hot loops. One of our engineers targeted a lot of the DOM manipulation in Dromaeo and we have a post on HTML5 Rocks to explain some of the gains we can add to the web platform. In this case, innerHTML is 240% faster before. Were really excited about that. And lastly, Id add that Chrome has tried to get out there with some ideas. Things like notifications, web intents, web audio API, and now web components. The Chrome team thought a lot about what we could do to help developers build significant applications, and
3/11
get implementations out there that people can play and build with. Its a priority for us to make the best web application experience possible.
How open is Google to receiving input from the developer community? How should developers go about affecting future changes to Google Chrome and Chrome dev tools?
Google is extremely excited about getting developer feedback. Part of this is getting the feedback delivered to the web standards working group responsible, when its CSS, JavaScript, DOM. And then when it comes down to the browser, for instance, on Chrome Developer Tools. I have hundreds of people pinging me weekly with ideas or have found bugs. I triage those regularly to get them in front of the engineers who can fix them. If you have a bug to report, first you should definitely search on the bug tracker. Theres the Chrome bug tracker and the WebKit bug tracker. Take a look and see if an idea or issue is already filed, and if its not, file it! Make your suggestion and pitch your use case on why its necessary. Then, let me know that you made it and I can triage it. Next, if you have an idea for how something should work, make a mock-up! A lot of times theres a good idea but no one has an idea of the right way to implement it. Lastly, with the Chrome developer tools, its just a webapp itself. Its written in JavaScript, so you can write a patch. In fact, the color picker in Chrome developer tools--was written by a web developer who decided we needed it enough to write the patch himself. Its way easier than youd think.
How important are dev tools, such as Chrome dev tools in web development? How robust are these tools?
4/11
that empower developers to build these modern web apps. I think we have good coverage for nearly everything people are doing. As far as how robust it is... One example I would give is this: debugging javascript is important and a first class feature for Chrome developer tools. Breakpoints, for example. We have a number of different kinds of breakpoints: Regular breakpoints; conditional breakpoints--that you break on if any certain expressions are true--breaking on certain event types; XHR breakpoints that match a certain string; DOM breakpoints, when DOM changes in a certain way; the debugger keyword inside a javascript file; and also breakpoints inside web workers. So we have good coverage, and if anyone thinks we dont have solid coverage for something, file it.
What dev tools should developers really be looking at?
I think performance and user experience are really important. Improving user experience has no tool, per say, I can really recommend for developers. But for performance, the first priority is network. PageSpeed Insights is a Chrome extension that gives a lot of great recommendations for network layer; making sure you utilized your network as well as you can. After that Id really recommend looking at the new frames view in timeline. This gives a great view of, for a specific action, whats actually happening inside a browser and how its putting together the page youre looking at. If its taking a long time, it shows if the browser is laying out the geometry of the page, painting it to the screen, or anything else. The tools gives you better idea of where to make changes for your optimization. The other tool I would probably mention is Speed Tracer. Its similar in scope to frames view, but catches little bit of different info. It gives you great ideas for how to speed up the performance of your web app.
5/11
Java developers enjoy having one single and massive IDE such as Eclipse, sometimes included in a collaborative platform such as IBM Jazz. Web developers seem to enjoy having multiple small tools, one tool per task. How do you explain this?
I think this is an interesting characteristic of the community. I this stems from is our awareness that the bytes we author are generally the bytes we send down the wire to our users. Were very filesize conscious. (Overly so, even) The sophistication of applications were developing has recently grown up quite a bit. There are things developers might have been doing in other environments for a long time that may not be standard practice. Unit testing is the one that comes up all the time. You ask folks if theyre unit testing, and you get about 50% of hands raised. Code linting, as a way of maintaining code quality. Code coverage for unit tests. Getting real time feedback in their apps. Some of these things are making the transition into standard workflow now, but its taking awhile.
Have you looked at Brackets, the open source code editor for the web published by Adobe?
I have and I think its fantastic. I love the quick edit feature where you can open a sub-editor that is related to the item youre selecting. If youre selecting an h1, quick edit shows all CSS style rules that affect that particular h1. I also like how it was developed. Its mostly with a modern javascript approach, using RequireJS, jQuery, Less, CodeMirror. Its fantastic that the team chose a stack that is very accessible to standard web developers, using a stack that theyre familiar with.
Which tools are missing today to power the best web development experience?
To be honest, I think we already have nearly all the tools we need. Its a matter of adoption. Some people are not aware these tools exist, other people dont think they need these tools, when they would probably benefit greatly from them. Theres also a lot of separate tools that could have better integration between them. This is something were targeting with the Yeoman project. As far as things that are definitely missing, I would say having sourcemaps for coffeescript would be fantastic. Also having Sass in browser development tools would be really excellent. In fact, however, both of these are under way. :)
6/11
Can you tell us a little more about HTML5rocks.com? What is the history? Intent? What were the goals upon setting out with creating the site?
The Chrome Developer Relations Team put together this site to create a home for people that want to develop web apps that push the web forward. We wanted to share what features are available now and how to use them the best. A huge amount of new features were emerging and didnt have great documentation. Now, two years later, its grown quite a bit and we have articles from 3rd party contributors, including Adobe, all covering the bleeding edge of web development.
What is the history and purpose behind HTML5 Boilerplate?
The history starts back when I was at my old job, making new sites and apps regularly and I noticed myself bringing over a lot of code from project. These patterns got codified and were born into the first versions. A little bit more of the history is in the HTML5 Boilerplate documentation. The first idea was for developers building webapps. But what it ended up morphing into was: 1: saving time; 2: the practices that developers were finding were now in a central place; 3: the project served as a vehicle for that education so more people could learn great ways to do things. So the project became a clearinghouse for front end techniques. The goal is now to be a solid default platform for building web applications.
What are HTML5 Please and CSS3 Please? Why were they created?
CSS3Please was created by some friends and I because typing out all the vendor prefixes for a certain property is annoying. I wanted something i could quickly manipulate and quickly cut & paste into my CSS. Nowadays CSS preprocessors and CSS mixins solve much of this problem. HTML5 Please serves the purpose of making the transition for people who have done this sort of before but dont know the best way to develop using new features. Recommending fallback scenarios and techniques. It came about because a lot of people wanted to use these features but didnt know the best way to put them into production. In some cases you can use a fallback. In other cases theres no responsible way to use a fallback; in that case we recommend to only have that feature available for the browsers that can handle it.
7/11
What is a good strategy for selecting tools when developing a web or mobile app when there are so many to choose from?
For tools that enhance your developer workflow... Id recommend perusing features they have. See if you can find a video of people using them, and how it integrates into their workflow. Then, try it out! Youd be surprised how much some tools improve your day to day routines.
The browser versions are being released at an alarming rate (well, some more than others). How is a web developer supposed to keep up with the changes and the requirements of supporting all those versions?
As far as keeping up, it can be hard. caniuse.com, chromestatus.com, hacks. mozilla.org, and the @chromiumdev twitter account try and capture whats brand new in browsers. Also html5rocks publishes information on whats new in Chrome and other browsers. Theres a lot of new features coming out all the time but even if youre not paying attention nothing will break you; if youre developing web apps in a responsible way, youll rarely need to change things between browser versions. But I do recommend keeping up to date on the latest browser news if youre targeting a fantastic user experience that takes advantage of everything available.
How has the onslaught of new frameworks affected web development? Has it made it easier for web developers? Created challenges?
8/11
Its made it easier, yes. I think it took a long time for client MVC to take hold, and developers were kind of stalled for a while. Now theres a whole lot of frameworks and libraries! While there is bit of a paradox of choice situation, I think its great that we have a lot of choices and a bit of competition. One problem here is javascript libraries can create a polarizing effect, and the fans become gangs that make it difficult for some people to proclaim an opinion. Thats not great. Id like to see more people taking a stand on how to do things, and also be open to change. For example, mobile, flaky connectivity and realtime are emerging as big influencers in how people choose the right stack.
Do you recommend using a methodology when developing a web application? Does this strategy change when you are developing a web application vs. a mobile application?
My methodology: Start out with planning, more planning than you expect. Set out your plan what stack of libraries and frameworks to use. Document your approach for CSS architecture. I also think when you pick a technology stack you should be flexible. Perhap, as you become more familiar with something, an alternative might become a better choice.
I also recommend setting aggressive browser support goals. I think its important you move legacy browsers up to date so you can give users the best possible experience using your app. For mobile in particular: build it offline by default. Its likely that for many of your users, connectivity will not be great. Build it from day 1 expecting that connection wont be present all the time. So start by assuming a bad connection and work from there. As a result, the user will have a much faster and more responsive experience.
Do you prefer to work alone or as part of a team?
I like a very social development experience. I like working as part of a team; working real time, and making use of an issue tracker that we can have some fun on. But for me its all about social activity and having fun.
Have you been involved in many projects that require making web applications accessible? Have there been many additions to HTML5 to make this feasible? Where have there been great strides in the area of accessibility? Where are there still challenges?
Accessibility in webapps is a tricky business and it may look a little hard to get your feet grounded in good practices, but Id recommend a few resources for this area: delicious.com/paul.irish/aria and html5accessibility.com.
9/11
There you can get a better feel for what is now available in HTML5 that directly assists accessibility. The top priority is really making sure your app is keyboard navigable. Target that and youll get 80% of the way there. Part of that is maintaining focus, for example, when dialogs pop up, you shift focus for the user to it.
You have initiated, or been heavily involved in, a lot of projects in your career (HTML5rocks.com, HTML5 Boilerplate, yayQuery, Modernizr, Type Rendering Project, Aurgasm, etc). Which of these projects have been the most influential or important in the world of HTML 5? Which have been the most fun?
A while ago I wrote a little bit about how browser update policies and was happy to see a pretty big impact there; a browser announcing an update policy thats much better (though Id still love to see more). I have some more ideas for projects that can have a big impact, and its always hard to balance my time when smaller immediate-gratification projects pop up. But working with a group makes all of these projects just a blast; I get to work with the best minds in frontend development and its such a pleasure every time to have that social experience with quick feedback loops.
Are there any special projects youd like to be able to spend more time on in the near future?
I actually just wrote and landed my first patch for WebKit! (Its a bit overdue, whoops!). I definitely want to keep hacking on the Chrome DevTools making some small changes that people have wanted for a while.
10/11
Ideally all our users are on very capable browsers. In reality, we have users stuck in older versions: in mobile we have Android browser which slows us down, on desktop its typically older IE versions. But the thing in common here is that these browsers do not have an update policy that keeps their users up to date. Instead they are left behind with zombie browsers. This very directly hurts our ability to develop rich applications because were supporting the lowest common denominator browser. We have a responsibility to assist our users to update them to more capable browsers. This creates a better experience for them and helps us push the web forward. Im working with some other smart folks in this area but would love to see more developers thinking responsibly about how we can best do this.
appliness
A lot of references I come across have far too much info, so this post will give examples and brief descriptions of some of the most common and useful string-related methods. I tried to put the most common ones near the top, for quick reference.
Of course, most experienced developers will be quite familiar with many of these, but I think this is a good list for beginners to understand the range of methods available that can help accomplish complex operations using simple syntax.
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
- get strings
- learn - manipulate
by Louis Lazaris
JavaScript
S t r i n g CONVERT
methods Cheat Sheet
to string
SPLIT
GET THE
LENTGH
OF A STRING
FIND THE
LOCATE A
SUBSTRING
WITHIN A STRING
REPLACE
A SUBSTRING
CHARACTER
AT A GIVEN
CONCATENATE
MULTIPLE STRINGS
SLICE
a String
POSITION
CONVERT A STRING TO
PATTERN COMPARE
MATCHING
UPPERCASE
TWO STRINGS
FOR SORT ORDER
FO
CU S
PH
EG
AP
BBC Olympics
by BBC & Adobe
FO
CU S
PH
EG
AP
appliness
FOCUS ON PHONEGAP
the second major release of phonegap has been unveiled on the 20th of july. here are the main new features of phonegap 2.0
what is phonegap ?
We already introduced this platform in the previous issues of Appliness. For those who need another introduction, here is a short description. PhoneGap allows developers to build cross-platform mobile applications using HTML5, CSS3 and Javascript. With PhoneGap, you can re-use your existing web developer skills and use the PhoneGap API to gain access to native features that arent accessible in mobile browsers. Building applications for each deviceiPhone, Android, Windows Mobile and morerequires different frameworks and languages. PhoneGap solves this by using standards-based web technologies to bridge web applications and mobile devices. PhoneGap has been downloaded over 1 million times and is being used by over 400,000 developers. Thousands of apps built using PhoneGap are available in mobile app stores and directories. Nitobi was the original creator and is one of the primary contributors to the PhoneGap framework. In October 2011, Adobe acquired Nitobi enabling the team to focus solely on the PhoneGap project and continue its work on efficient development across mobile platforms. The PhoneGap code was contributed to the Apache Software Foundation (ASF) under the name Apache Cordova. Through the ASF, future PhoneGap development will ensure open stewardship of the project. It will always remain free and open source under the Apache License, Version 2.0.
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
by Colene Chow
PhoneGap 2.0 is all about a vastly improved developer experience, Our docs are now much more comprehensive, including the long requested commitment to our Plugin API. Developers are going to have a supported way to use the PhoneGap bridge to build their own browser APIs for native calls. Brian Leroux - Lead Developer for PhoneGap
the new features
Here are the major new features in PhoneGap 2.0: Cordova WebView This allows for the integration of PhoneGap, as a view fragment, into a bigger native application. Command Line Tooling (CLI) CLI tooling brings a standard nomenclature to common tasks across platforms such as project creation, debugging, and emulation. Normally, these are different incantations for each platform vendor making cross platform development workflow inconsistent and jarring; weve fixed that. Enhanced documentation Getting-started guides, plugins, migration guides and more to help accelerate the development of mobile applications and make it even easier. Web Inspector Remote (Weinre) ported to nodejs The availability of a node module means easy installation using Node Package Manager (NPM). Cordovajs (Support for unified Javascript across platforms) Weve seen dramatic advancements to performance, security, and API symmetry across platforms thanks to the herculean effort of unifying our JS layer. Transition to Apache Cordova and nearing graduation from incubation Windows Phone support Improvement to iOS app creation Weve implemented significant changes for the iOS platform. Get a deeper dive into all the changes from Shaz, our PhoneGap iOS lead developer.
The PhoneGap community is bigger and stronger than ever with new contributors since last year like Adobe, Google, Microsoft, RIM and HP. With a bigger community and additional resources from Adobe were shipping new versions of PhoneGap much faster than a year ago. Andre Charland - director of Engineering for PhoneGap
FO
CU S
PH
EG
AP
appliness
FOCUS ON PHONEGAP
piotr is explaining in two videos how to get started with phonegap 2.0 to build ios and android mobile applications.
few steps
As you may already know PhoneGap 2.0 was released last month. This is a major release that brings some new features and lots of changes around the way you create and setup your development environment. For example to create a new iOS/PhoneGap project you dont use a wizard from Xcode anymore; now you need to launch a bash script from command line. Below you will find two short video tutorials that demonstrate how to get started for both Android and iOS platforms. Also after the videos you can find some additional steps that I had to go through in order to get everything running properly. I know these steps may not be necessary for all. Ive tested it also on my colleagues less polluted Mac and everything worked out of the box .
Difficulty
- rookie - intermediate - expert
Todo list
- setup - command line - deploy
by Piotr Walczyszyn
2/4
directory error If you happen to get the following error: Error: No developer directory found at /Developer. Run /usr/bin/xcode-select to update the developer directory path. You can fix it by the invoking following command, with the path after the -switch parameter pointing to where you have Xcode installed: sudo /usr/bin/xcode-select -switch /Applications/Xcode.app/Contents/Developer ios simulator If you want to run iOS Simulator from the command line you will need to install the ios-sim app that is available on GitHub. Not having ios-sim may also result with a following error in a console when running a debug script: Error: ios-sim was not found. Please download, build and install version 1.4 or greater from https://github.com/phonegap/ios-sim into your path. Or brew install ios-sim using homebrew: http://mxcl.github.com/homebrew/
3/4
The easiest way to install ios-sim is to use homebrew. To install homebrew you either follow the instruction on its website, or just invoke the following script: /usr/bin/ruby -e $(/usr/bin/curl -fsSL https://raw.github.com/mxcl/homebrew/ master/Library/Contributions/install_homebrew.rb) After homebrew is installed you may want to run its doctor function to verify that everything was setup correctly: brew doctor If brew doctor says everything is alright just run this: brew install ios-sim project size You may wonder why the size of iOS projects has grown significantly to something like ~15MB. This is because starting from PhoneGap 2.0 a default project contains assets like splash screens and icons for new iPad Retina displays. So if you are not targeting these new devices make sure you remove these assets and you should be back to something like 1+ MB
4/4
FO
CU S
PH
EG
AP
appliness
FOCUS ON PHONEGAP
Talented developers such as andrew trice or christophe coenraets developed many mobile applications using phonegap. Most of them are open source. Discover and download these FOUR great projects to become a phonegap master.
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
- learn
- download - hack
by PhoneGap fans
and more. The application allows you to experiment with the APIs most frequently used parameters and see the results instantly inside the application. You can also click the API button and access the complete documentation for the API you are experimenting with. The application is built with Backbone.js, and Twitter Bootstrap, and it is of course wrapped with PhoneGap.
Im also making the source code for this application available in this repository on GitHub: https://github.com/ccoenraets/phonegap-explorer
Im also making the source code for this application available in this repository on GitHub: https://github.com/ccoenraets/employee-directory-app
2/4
LIL DOODLE
by ANDREW TRICE Back in January I released Lil Doodle, a childrens drawing application for the iPad built with PhoneGap. Lil Doodle is meant for a simple sketch-and-erase experience similar to a childrens magnetic drawing toy, powered entirely by JavaScript and the HTML5 Canvas element. A few notes about the Lil Doodle application: - This app was designed specifically for the iPad. The UI is specifically styled for the iPads portrait form factor. The code is also specifically setup for touch events. If you try to run this code in the desktop browser, you will get layout and runtime JS errors. - The sketching for this application does work on other platforms (Android, BlackBerry, etc), however at the time of release, only the HTML5 Canvas on iOS performed well enough to release. This is because the HTML5 Canvas element on iOS is hardware accelerated. The HTML5 Canvas on BlackBerry Playbook OS 2.0 is now hardware accelerated, however, I have not repackaged and tested the app on that platform. The HTML5 Canvas inside of webview elements in Android is not yet hardware accelerated. - Lil Doodle supports multiple touch points, where the brush images example, only supports a single touch point. - Lil Doodle DOES NOT update the canvas on every touch event if you did so, you would have runtime performance issues. Instead, it caches the touch locations, and updates the visual canvas inside of a render loop (target 60FPS). Using this approach, I was able to get very good performance, even with multiple touch points. The loop currently uses JS timeouts b/c iOS 5 and earlier do not support requestAnimationFrame.
Ive decided to release the source code of this application to demonstrate how you can create interactive drawing experiences for PhoneGap applications. You can access the full source of this application at: https://github.com/triceam/Lil-Doodle
3/4
The Fresh Food Finder uses the following technologies: PhoneGap: http://www.phonegap.com - PhoneGap is an HTML5 app platform that allows you to author native applications with web technologies and get access to APIs and app stores. App-UI: http://triceam.github.com/app-UI/ - App-UI is a free & open source collection of reusable application container user interface components that may be helpful to web and mobile developers for creating interactive applications using HTML and JavaScript, especially those targeting mobile devices. Mustache: https://github.com/janl/mustache.js - Mustache is a logic-less template syntax. It can be used for HTML, config files, source code anything. It works by expanding tags in a template using values provided in a hash or object. jQuery: http://jquery.com/ - jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. Leaflet: http://leaflet.cloudmade.com/ - Leaflet is a modern, lightweight open-source JavaScript library for mobile-friendly interactive maps.
The entire user interface of the application is created dynamically at runtime based on JavaScript and the Mustache templates. You can download the full application source code: https://github.com/triceam/Fresh-Food-Finder
FO
CU S
PH
EG
AP
appliness
At a recent PhoneGap Day, I saw a demo showing the AppLaud Eclipse plugin by Mobile Developer Solutions (MDS), a plugin for creating PhoneGap templates to make your PhoneGap/Cordova for Android development fast and easy. I found it particularly interesting as I had discovered this pain point myself and been trying to address it with my own set of templates, but always thought a plugin would be ultimate. It appears the MDS folks concurred and were nice enough to share.
ou Playgr
nd
Difficulty
- rookie - intermediate - expert
Todo list
- create
- install - configure
by Holly Schinsky
You can use the Android option to point to the installed SDK path such as shown below:
Next, install the AppLaud plugin in Eclipse by going to Help | Install New Software and point to this URL: http://svn.codespot.com/a/eclipselabs.org/mobile-web-development-with-phonegap/tags/r1.2/ download.
Hit Next and then Finish on the next dialog and you will be prompted to reboot Eclipse for the new plugin to be available. Note: If you have any trouble, more details on installing the plugin can be found on the MDS site.
2/9
Create an Application
Once Eclipse has been restarted you should see a new Project option for your newly installed plugin. If you go to File | New | Project, you should now see an option to create a PhoneGap for Android Project such as shown here:
The AppLaud plugin is handy because it gives you the option to create a blank project or options to create a project containing a couple different UI libraries depending on your preference (includes jQuery Mobile and Sencha Touch options). You also have the option to create an application template that includes PhoneGap API sample code for GeoLocation, Accelerometer, Compass, Camera, Files, Contacts and more. This is something I actually created a template to address myself, but having it included in a plugin is even better.
3/9
If you have a newer version of PhoneGap you want to use, theres an option to enter the path to it as well. For instance, PhoneGap 2.0 was announced recently at PhoneGap Day, so I would prefer to use that over 1.9 which is the current built-in version. I can do that by specifying the path to the root folder unzipped from the downloaded file shown here:
4/9
Notice the project is automatically set up for you to include the correct Cordova JavaScript and JAR files in the proper place, along with the default Java activity and AndroidManifest.xml all set up and ready to go. Note: at this point you may have received this error depending on your versions error: No resource identifier found for attribute xlargeScreens in package android AndroidManifest.xml /AppLaudTest line 9). If that happens, remove the xlargeScreens property line from the supports-screens element in the AndroidManifest.xml file and once saved the error should go away: <supports-screens android:largeScreens=true android:normalScreens=true android:smallScreens=true android:xlargeScreens=true android:resizeable=true android:anyDensity=true />
5/9
The generated project template in this case will include a main.js file that contains all the functions used by index.html to invoke PhoneGap API functions. Heres a snippet from the generated main.js: ... var deviceInfo = function() { document.getElementById(platform).innerHTML = device.platform; document.getElementById(version).innerHTML = device.version; document.getElementById(uuid).innerHTML = device.uuid; document.getElementById(name).innerHTML = device.name; document.getElementById(width).innerHTML = screen.width; document.getElementById(height).innerHTML = screen.height; document.getElementById(colorDepth).innerHTML = screen.colorDepth; }; var getLocation = function() { var suc = function(p) { alert(p.coords.latitude + + p.coords.longitude); }; var locFail = function() { }; navigator.geolocation.getCurrentPosition(suc, locFail); }; var beep = function() { navigator.notification.beep(2);
6/9
}; var vibrate = function() { navigator.notification.vibrate(0); }; function roundNumber(num) { var dec = 3; var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); return result; } var accelerationWatch = null; function updateAcceleration(a) { document.getElementById(x).innerHTML = roundNumber(a.x); document.getElementById(y).innerHTML = roundNumber(a.y); document.getElementById(z).innerHTML = roundNumber(a.z); } var toggleAccel = function() { if (accelerationWatch !== null) { navigator.accelerometer.clearWatch(accelerationWatch); updateAcceleration({ x : , y : , z : }); accelerationWatch = null; } else { var options = {}; options.frequency = 1000; accelerationWatch = navigator.accelerometer.watchAcceleration( updateAcceleration, function(ex) { alert(accel fail ( + ex.name + : + ex.message + )); }, options); } }; ...
7/9
Below are a couple of screenshots showing this template application running on my Android Nexus One:
8/9
FO
CU S
PH
EG
AP
JOSHFIRE
THEPHONEGAP&WEBMASTERS
The internet of things is part of our DNA and we have a strong hacker culture.
1/8
Joshfire is a very innovative agency. What sets Joshfire apart to make them unique?
The internet of things is part of our DNA and we have a strong hacker culture. We think that using web technologies is a perfect solution for solving the current multi-device fragmentation. Developing an app for a mobile or smart TV is not so far from creating a UI for an interactive mirror or a digital table... We see the multi-device boom as a first step. The next move will be the rise of the internet of things, not only as an M2M network, but also as huge market of surfaces and connected things dedicated to content and service consumption. At Joshfire, once a month we organize an internal hackathon where the result has to be cross-device, made with Web technologies and involve hardware hacks (we all have our own Raspberry Pi and we use Arduino and OpenPicus boards a lot). Additionally, our small team is quite active in the event community in Paris. To name a few, Joshfire employees are organizers of or involved in: HackDay Paris, Music Hack Day (organized with UNESCO and Google), Hackers News Meetup, ParisJS, PhoneGap Paris, TEDxParis, TEDxConcorde and finally dotJS, the largest international JavaScript conference in France to be held in Paris.
As true web fans and web experts, you have developed mobile applications using PhoneGap such as Adrenaline for a famous French press group. Can you introduce the key features of this application?
The application is available for iPhone, iPad, Android phones and tablets. Its user interface is different depending on the type and brand of the running device: Tablets present a two column layout and phones a singleview one. Position of the buttons are different on Android and iOS: for example, on phones, action buttons are at the bottom on the iPhone and at the top on Android (it mimics Androids action bar pattern). Fortunately, they all run the same codebase. The application lets the user fluidly browse and play a catalog of videos. It is ad-supported (interstitial screen, top-banner and pre-roll video). Users can share the videos on their favorite social networks. They can also receive news from push notifications.
Was PhoneGap a natural choice for this application? Have you considered other technologies?
2/8
We didnt really consider other technologies. Mostly all of our developers are proficient with JavaScript and we already had the expertise for building PhoneGap-based applications.
And we knew that we could rely on Phonegap extensibility using plugins (for instance we built custom plugins for iOS and Android in order to display the ads).
Im a JavaScript engineer at Joshfire, organizer of PhoneGap Paris meetups and regular ParisJS MC - Thomas Bassetto
3/8
For which kind of mobile applications do you recommend hybrid development with PhoneGap?
We do not develop games, but for the other apps targeting regular consumer and enterprises we recommend hybrid development with PhoneGap. People always forget the extensibility of PhoneGap and the fact that you can call any API from the official SDKs and build any native widget if you want. Of course, using PhoneGap instead of directly using official SDKs adds some layers of code to execute and you may notice a small drop on FPS on apps that heavily use transitions and animations. That has never been a showstopper for us or our clients.
You also organized the TEDx conferences in Paris. Could you describe this event in a few words?
TEDx is a program created by TED to allow their community to organize local TED-like events. Joshfire founders created TEDxParis in 2009. Today, the TEDxParis event is one the most famous TEDx events in the world. The TEDxParis community is growing very fast (doubling each time we organize a new event). The next TEDxParis will take place at lOlympia on October 6.
The TEDx Paris application has been featured in the App Store. Its also a PhoneGap application. Can you describe this application?
The TEDxParis app lists all the previous editions of the conference and is used mainly to watch recorded performances. Weve been fortunate to not only be featured on the AppStore but also on a TV ad in the French Television (where Apple was showcasing the iPad).
Do you feel that hybrid development is a temporary solution? What APIs are missing in mobile browsers today to deploy native-like applications?
We all know that the ultimate purpose of PhoneGap is to cease to exist. The web is not a first class development platform: lack of debug tools, missing APIs, and a rather limited set of GUI elements. Fortunately, the landscape is changing quickly thanks to the work we see at the W3C, WHATWG, and other research such as Mozillas WebAPI, WAC, Tizen and the like. We may be able to stop relying on PhoneGap once about 90% of mobile web browsers used will support APIs to access the camera, the file system and others various sensors. We have faith in Firefox, Opera and Chrome but less in Safari on iOS. We dont see Apple allowing those kind of APIs in the browser soon.
4/8
Im the co-founder & CTO of Joshfire, cofounder of TEDxParis+TEDxConcorde and founder of Jamendo - Sylvain Zimmer
You only need to know front-end web development to become a PhoneGap developer. But to become an excellent PhoneGap developer (or HTML5 app developer) you need to have good knowledge about memory management, proper handling of pause/resume events and handling loss of connection, touch events and how a browser works internally. Its kind of fun to see that some of the best HTML5 app developers have a background in developing native desktop apps or Flash apps with a high framerate.
How would you describe the mission of a web developer in todays world?
The web developer mission has always been and will always be to develop for the widest audience possible. Thats why we think we should embrace the Web as it is, browsers as they are and stop developing for only one engine. We do our best to have a great experience on the maximum of device and browsers, so should do other developers. As things are evolving quickly, its also important to share knowledge and contribute to Open Source. Most web developers learn from shared code and tutorials, thats why we encourage our developers to write technical articles on our company blog.
5/8
Could you give some advice to our readers who would like to develop PhoneGap applications? Any framework recommendations?
jQuery Mobile is great for cross-patform and quickly create a Proof-Of-Concept but may be a bit heavy for building your final app. Weinre, iWebInspector and Adobe Shadow are indispensable for inspecting remote applications. If you can, use Chrome Mobile remote debugging which has more features. The brand new http://emulate.phonegap.com with Ripple is also a great tool for debugging (you can use the standard Chrome Desktop Dev Tools to debug PhoneGap applications) Zepto.js replaces jQuery in almost all our mobile app development.
Im an engineer and the product manager of the Joshfire Factory, organizer of a couple of hackathons in Paris - Steren Giannini
What is the Joshfire Factory?
The Joshfire Factory is an online tool that speeds-up application development and deployment. The creation process involves the selection of datasource connectors, an application template, possible add-ons, and the list of devices to target. Within minutes, the Factory may generate Web applications and binaries for all types of screens and platforms. The current version is compatible with Web applications, iOS, Android, BlackBerry, Windows 8 Metro, GoogleTV, Samsung, Philipps and LGconnected TVs.
6/8
Joshfire doesnt only use web technologies to develop mobile applications. You use the web platform to develop innovative objects. Can you tell us more? Are you currently working on any new innovative projects that involve web technologies ?
We leverage the Open Web platform to develop all sorts of projects, notably during our internal hack days. All of our products communicate together using the HTTP protocol and we use Node.js to build all of our servers, even those communicating with Arduino boards. For instance, our connected and interactive mirror interface is based on a web browser and everything that runs inside is an HTML5 app. We also use web technologies for our sofa that can auto-pilot your GoogleTV. Lastly, we built a drop-shaped object that allows customers to order bottles of water from their fridge. We used web technologies to iterate quickly and test our changes as soon as possible on the device.
Joshfire enhances everyday objects. How have these enhancements affected peoples everyday lives?
A hackday is an event in which developers, designers and project managers, collaborate intensively on new projects. They are often software-related but they could be music-related or just artistic. Our team organized several public hackathons (some of them with Google and UNESCO and soon with France Televisions) but we also do internal hackathon. In both cases, no final consumer products resulted from them. Our goal is to see the best we can do in 24h to 48h, not more.
7/8
Can you describe a typical day (if there such a thing) in an office where such creative products are produced?
All of our employees are free to adapt their schedule as long as the work is done and they are present for the company meeting on Monday mornings. We also have lunch together in our huge Iron Chef-like kitchen. The bravest cook their meal at the company :)
What is yet to come from Joshfire in the years ahead?
Put the Factory at the central piece of connected objects and multi-device applications. The last part is very important for us, we want to allow people to create apps for everything from TVs to connected appliances. Well also open offices closer to strategic points like NYC and Asia.
FO
CU S
PH
EG
AP
appliness
SHOWCASE
BBC Olympics
THE BBC is the largest boradcaster in the world. for the olympics, the bbc has released on the app store a mobile application built with phonegap and primetime.
This application has been developed web standards and PhoneGap. Users will enjoy a neat UI and a classic navigation bar at the bottom of the screen. It features editorial content such as top stories, live text commentaries from BBC journalists, medals table, a page for every competing country, etc... But the main innovation resides in usage of videos. The BBC employs the Project Primetime to power its coverage of the Olympic Games to millions of mobile and connected devices across the UK for the first time in history. Its using HTTP Dynamic Streaming (HDS) and HTTP Live Streaming (HLS) to stream live and on demand video across desktops, connected TVs and iOS devices. Adobe Media Server is working in the background to encode and stream the content. BBC also implemented adaptive bitrate video playback available in the Open Source Media Framework (OSMF). - More information about PhoneGap - More information about Project Primetime - More information about OSMF
We needed to ensure everyone could access our coverage. Phil Fearnley, General Manager BBC News & Knowledge
appliness
Fresh news about HTML and Javascript collected by Brian Rinaldi - remotesynthesis.com
Mastering the Application Cache Manifest for Offline Web Apps and Performance via Julien Nicault Preparing Yourself for Modern JavaScript Development via Justin Etheredge
Using CSS Sprites to optimize your website for Retina Displays via Maykel Loomans
Implementing a command line with eval in JavaScript via Dr. Axel Rauschmayer
appliness
Databinding UI Elements with IndexedDB via Raymond Camden More efficient CSS3 transitions via Val Head
SURVIVOR: Remaking A Commodore 64 Game In HTML via Scott Schiller The CSS Guide via InsertHTML
Working with large integers in JavaScript via Dr. Axel Rauschmayer An Introduction to the CSS Flexbox Module via NetTuts
Writing a Flippable Book Using CSS Regions and 3D Transforms via Ilmari Heikkinen
appliness
THE TEAM
Contribute and join Appliness
Appliness is a free digital magazine edited by passionate web developers. We are looking for contributors. Contact us and join the adventure. Youll find on our website appliness.com a feedback form. You can also follow us on twitter, facebook and Google+.
MICHAEL
Michal Chaize is a Developer Evangelist at Adobe where he focuses on Rich Internet Application and Mobile applications. Based in Paris, he works with large accounts that need to understand the benefits of rich user interfaces, leverage the existing back-ends to add a rich presentation layer and measure the impact on the existing IT teams. He believes that intuitive user experiences in the Enterprise are key to successful developments of effective, efficient, engaging, easy to learn and error free applications. Before joining Adobe, Michael founded a software company and taught RIA languages such as Flex and PHP in IT engineering schools. Hes the editor in chief of Appliness.
CHAIZE
R AY M O N D
Meet Raymond Camden. He is a 38 year old married father of three living in beautiful Lafayette, Louisiana. Ray is a developer evangelist for Adobe where his primary technical focus is ColdFusion, jQuery, Flex, AIR and the mobile space. Hes been invited to speak at many conferences over the years, including CFUNITED and Adobe MAX .
CAMDEN
LOUIS CHRISTOPHE
Christophe is a Developer Evangelist for Adobe where he focuses on Web Standards, Mobile, and Rich HTML Applications with a special focus on Enterprise Integration. In this role, Christophe has helped some of the largest financial services companies design, architect and implement some of their most mission critical applications. He was one of the initial members of the Flex Product Team in 2003. In his previous role at Macromedia, Christophe worked on JRun, the companys J2EE application server. Before joining Macromedia, Christophe was managing Java and Internet Applications Evangelism at Sybase and Powersoft. Christophe has been a regular speaker at conferences worldwide for the last 15 years.
COENRAETS
Louis Lazaris is a freelance web developer based in Toronto, Canada. He blogs about front-end code on Impressive Webs and is a co-author of HTML5 and CSS3 for the Real World, published by SitePoint.
LAZARIS
NICHOLAS C.
ZAKAS
B R I A N
Brian Rinaldi is as a Content and Community Manager for the Adobe Developer Center team, where he helps drive content strategy for HTML5 and JavaScript developer content. Brian blogs regularly at http://remotesynthesis.comand and is a unreformed twitter addict.
RINALDI
Nicholas C. Zakas is a front-end consultant, author, and speaker. He worked at Yahoo! for almost five years, where he was front-end tech lead for the Yahoo! homepage and a contributor to the YUI library. He is the author of Maintainable JavaScript (OReilly, 2012), Professional JavaScript for Web Developers (Wrox, 2012), High Performance JavaScript (OReilly, 2010), and Professional Ajax (Wrox, 2007)
TERRENCE
Terrence Ryan is a Worldwide Developer Evangelist for Adobe. His job basically entails traveling the world and talking about the developer tools and technologies that Adobe has to offer or that evangelists support.
R Y A N
P I O T R
W alczyszyn
Piotr Walczyszyn is a technology geek leaving in Warsaw, Poland, where he was born. outof.me is his new blog in which he wants to express his current interests and share some of his work. Technologies change; new trends come and go. These days nobody talks about RIAs (Rich Internet Applications) anymore, and he thinkd this phrase has become almost pass although its main concepts have not.
A N D R E W
Andrew Trice is a Technical Evangelist with Adobe Systems. Andrew brings to the table more than a decade of experience designing, implementing, and delivering rich applications for the web, desktop, and mobile devices. He is an experienced architect, team leader, accomplished speaker, and published author, specializing in object oriented principles, mobile development, realtime data systems, GIS, and data visualization.
T R I C E
M A I L E
Maile is the assistant editor for Appliness magazine and has worked with Adobe both as an employee and consultant for 8 years now. Mailestarted with Adobe on the Technical Marketing team as a technical trainer for the Adobe LiveCycle Enterprise Suite (most recently Adobe Digital Enterprise Platform). She then went on to work with the Adobe Enterprise Evangelist team to support great Flex developer resources such as Tour de Flex and Flex.org. Maile is excited to jump into the world of digital publishing and dig deeper into leading edge HTML and related technologies.
VALENTINE
Greg is a Developer Evangelist at Adobe Systems focusing on the use of Adobe technologies in enterprise applications. Technologies include HTML, JavaScript and related technologies, Flex, AIR, data services, digital publishing, and anything mobile, tablet and desktop app development related. Prior to joining Adobe, Greg architected and developed many largescale applications at Verizon, Motorola, NASA/Boeing and others.
WILSON
H O L L Y
Holly is a Developer Evangelist at Adobe Systems and has been doing software development since 1996 with experience working for various Fortune 500 companies to startup. Hollys experience is primarily in OO languages, but she thrives on constantly learning new things & is always up for a challenge.
S chinsky
Appliness is a digital magazine written by passionate web developers. You can follow our activity on Facebook, Twitter or Google+.
O W FO LL
o t t n a w ? u e Yo ribut t n co
U S
If you want to contribute writing articles or showcasing your app, feel free to contact us. We are permanently looking for new contributions and content to cover all the aspect of application development with web standards. We are also opened to suggestions. The Give us feedback form on our website is the best way to contact the team.
GIVE US FEEDBACK
CO
TR I
BU
TE