Activate your free membership today | Log-in

Friday, August 22nd, 2008

Emulating onhashchange without setInterval

Category: Ajax, JavaScript

IE 8 has an onhashchange event, and Ajax history / bookmark management has been a long time problem of choice for developers.

Zach Leatherman has revisited the problem and has another solution that doesn’t require setInterval to check on the location.

  1. On initialization, we load an iframe onto the page that is positioned absolutely at -500px,-500px so the user can’t see it. It is a skeleton page that only needs cross browser code to add an “onscroll” event, and to be able to calculate the scrolled position of the iframe itself. For my example, I use jQuery and the dimensions plugin to accomplish this, but it could easily be trimmed down to only the bare essentials (or ported to a different library).
  2. To add an AJAX history entry into the browser’s history under an assigned hash string, we first add a <a name="hashString">hashString</a> to the <body> tag of the iframe. Using css to increase the size of the a tag proportional to the iframe’s height, we can guarantee scrolling will happen.
  3. Then, we change the location.hash of the iframe to point to that <a> tag. This will scroll the iframe to the content, and create a new entry in the browser’s history object.
  4. Inside the iframe, we have our onscroll event that fires when the scrolling in the previous step took place. (Minor IE-related workaround: The browser’s history object is changed, but the hash property doesn’t when attempting to read it later. Instead, we find the <a> that matches up with the scrollY/pageOffsetY property inside of the iframe, and retrieve the matching hash from the <a> tag.)

The solution gives you history management and back button support in one fell swoop, with the side effect of not having bookmarkability (since the iframe is updated).

Posted by Dion Almaer at 7:16 am
9 Comments

++++-
4.4 rating from 7 votes

Wednesday, July 23rd, 2008

window.name meet dojox.io.windowName

Category: Ajax, Dojo, JavaScript

We have written about using window.name as a transport and Kris Zyp has just posted about how Dojo has created a new dojox.io.windowName module.

The window.name transport is a new technique for secure cross-domain browser based data transfer, and can be utilized for creating secure mashups with untrusted sources. window.name is implemented in Dojo in the new dojox.io.windowName module, and it is very easy to make web services available through the window.name protocol. window.name works by loading a cross-domain HTML file in an iframe. The HTML file then sets its window.name to the string content that should be delivered to the requester. The requester can then retrieve the window.name value as the response. The requested resource never has access to the requester’s environment (JavaScript variables, cookies, and DOM).

You can access it in a simple way:

JAVASCRIPT:
  1.  
  2. dojox.io.windowName.send(method, args); // simple method
  3.  
  4. // deferred result
  5. var deferred = dojox.io.windowName.send("GET", {url:"http://somesite.com/resource"});
  6. deferred.addCallback(function(result){
  7.   alert("The request returned " + result);
  8. });
  9.  

Kris then goes on to show how to use this with Web services and other scenarios, and explains why you may be interested:

This technique has several advantages over other cross-domain transports:

  • It is secure, JSONP is not. That is, it is as secure as other frame based secure transports like fragment identifier messaging (FIM), and Subspace. (I)Frames also have their own security issues because frames can change other frames locations, but that is quite a different security exploit, and generally far less serious.
  • It is much faster than FIM, because it doesn’t have to deal with small packet size of a fragment identifier, and it doesn’t have as many “machine gun” sound effects on IE. It is also faster than Subspace. Subspace requires two iframes and two local HTML files to be loaded to do a request. window.name only requires one iframe and one local file.
  • It is simpler and more secure than Subspace and FIM. FIM is somewhat complicated, and Subspace is very complicated. Subspace also has a number of extra restrictions and setup requirements, like declaring all of the target hosts in advance and having DNS entries for a number of different particular hosts. window.name is very simple and easy to use.
  • It does not require any plugins (like Flash) or alternate technologies (like Java).

Posted by Dion Almaer at 7:08 am
6 Comments

+++--
3.6 rating from 37 votes

Thursday, July 3rd, 2008

OpenLaszlo 4.1: DHTML ready for primetime

Category: Adobe, Ajax

OpenLaszlo is a fascinating project, and got even more interesting when they went meta, and allowed you to general Ajax applications as well as SWF ones. The 4.1 release is a big one, as it brings full parity to the Ajax side of the house:

OpenLaszlo 4.1 is a major release bringing full support for both the DHTML/Ajax and the SWF/Flash platforms. It also includes over 800 bug fixes and a significantly improved documentation suite.

OpenLaszlo 4.1 has been fully-qualified across the following browser/platform combinations: Safari3/OSX, Firefox2/OSX, Internet Explorer 7/WinXP, Firefox 2/WinXP, and Firefox 2/Linux. We have tested the full suite of demos, samplers, and example applications with the requirement that, when possible, DHTML applications behave the same as their SWF counterparts.

OpenLaszlo 4.1 is now the recommended release for all developers on all platforms, and current users of OL 3.x and 4.0 should investigate upgrading to this new release.

Preliminary support for SWF9 is included in this release but has not been enabled in the developer console.

At the same time, the team announced 500,000 downloads. Congrats!

Posted by Dion Almaer at 10:19 am
2 Comments

+++--
3.7 rating from 39 votes

Wednesday, June 25th, 2008

flXHR: Flash based XHR from flensed

Category: Ajax, Flash, JavaScript, Library

Kyle Simpson has announced a new family of opensource projects called flensed and the first project being flXHR which "utilizes javascript+flash to create a complete, literal drop-in replacement (by being API identical) for the native browser XHR (Ajax) communication mechanism. However, flXHR uses Flash Player's security model to enable direct cross-domain communication, and also has a number of other very helpful extensions."

http://flxhr.flensed.com/code/tests/flxhr-4.html

There are a number of demos which illustrate how it easy it is to take the API-compatible flXHR and swap it to any of your favorite JS frameworks (Dojo, Prototype, YUI, ExtJS, etc) in place of its usage of native XHR... once the simple adapt/swap happens, everything else about the framework library communication works the same, because flXHR speaks the same familiar protocol and API, and so it really is what I like to call "set it and forget it" good.

Hasn't this been done before?

There have been several other attempts at similar things before, including SWFHttpRequest, FlashXMLHttpRequest, Fjax, and F4A. However, all those fell short of the mark in different ways. On my site, there are comparison charts and detailed FAQ's which show how flXHR stands up to these predecessors, and exceeds them in very important and powerful ways. I believe flXHR has accomplished its goal, which was to be *the* complete solution for SWF-based Ajax calls as an identical API-compatible drop-in replacement for native XHR, not to mention many helpful improvements including robust error callback handling, timeouts, and convenience configuration functions, to name a few.

Posted by Dion Almaer at 9:53 am
21 Comments

++++-
4.2 rating from 29 votes

Friday, June 20th, 2008

jsTree: jQuery-based JavaScript tree component

Category: Ajax, Component, JavaScript

Ivan Bozhanov walked us through his jQuery-based tree component recently. The state of trees out there is interesting. YUI! has a nice, stable tree control but Dojo's once feature-rich tree has been replaced with a fairly basic tree (i.e., doesn't appear to have in-line editing and drag-and-drop still seems flakey; Dojo guys, correct me if I'm wrong) at the moment and jQuery UI lacks an official tree component (though a few tree plug-ins are out there); as you might expect, Ext JS has a nice tree component.

Let me highlight a few areas where jsTree stands out. First, it has some basic features that many trees out there lack:

jsTree allows the user to create, rename, reorder, move, and delete note (which is realised in a file-browser manner - eg. inplace)

It also has a rich event API which is fairly standard across most editable tree components, though the event types are finer-grained than in most trees I've seen (not sure whether that's a good thing):

You can attach callbacks to almost every action:
- onbeforechange
- onchange
- onrename
- onmove
- oncreate
- ondelete
- onopen
- onclose

It also allows you to provide rules that govern what the user may or may not do based on the "type" of a node:

jsTree lets developers define rules for moving, selecting, deleting, and focusing nodes. The rules are based on developer-definable types of each node passed in the data (different sources define it differently). This limits the user in his actions. The developer can also attach inline rules which override global rules. One scenario in which these rules are useful is when you build a CMS and need a fixed number of top level nodes because of a design restriction.

While you could accomplish the same functionality with event handlers, it's nice to have a simple built-in scheme that can be easily data-driven.

These rules are applied real-time as the user attempts to interact with the tree:

When you drag a node around a pointer tells you where you are about to insert it, and prevents the user from dropping anywhere against the rules. The warning is real time - as you drag and drop the pointer is replaced by a red cross if the action is against the defined rules. I'm still working on displaying definable text messages.

jsTree can be configured to reference a custom property in each node object to determine its type.

It also has built-in localization support; you specify string identifiers corresponding to the different languages that the tree should support on construction:

JAVASCRIPT:
  1. tree1.init($("#nested"), {
  2.     data : "nested.xml",
  3.     xsl : "nested.xsl",
  4.     languages :  [ "en", "bg" ],
  5.     // other stuff omitted
  6. });

and then in this case each node in the XML tree fed to the component specifies its language:

XML:
  1.  
  2. <name lang="bg" icon="images/f.png">Начало</name>
  3. <name lang="en" icon="images/f.png">Home</name>
  4.  

In addition to XML data types, it also supports JSON and in-line HTML. But it also has built-in support for doing XSL transforms on XML data sources, including a scheme that lets you include flat data that it then makes into a hierarchy:

jsTree supports XSL transformations when using the XML data source option. This is a bit faster than javascript parsing. It includes an XSL stylesheet for transforming a flat list of entries into a tree. This can be useful if you use adjacency for maintaing a tree in a database. In such situations it is quite heavy on the server to dump the whole tree as you need N-1 queries where N is the number of nodes in the tree. With this XSL solution you can just dump the table flat out with id and parent_id attributes and the XSL will transform it into a nested structure.

Unfortunately, what jsTree is lacking is the visual refinement of many of the trees out there, but as jsTree is built on top of jQuery, we suppose Ivan can add that kind of polish easily.

For many data-driven applications, high-quality grid and tree components are really important; kudos to Ivan for some interesting ideas in jsTree. The docs are certainly better than some I've seen, but not as complete as I'd like.

Posted by Ben Galbraith at 5:00 am
11 Comments

+++--
3.9 rating from 42 votes

Monday, June 16th, 2008

modules.js: A New Stand-alone JavaScript Module Loader

Category: Ajax, JavaScript

Kris Kowal dropped us a line pointing us towards his year-long labor of love: modules.js, a stand-alone dynamic JavaScript module loader.

As the module-loading space is quite crowded at the moment (e.g., Google, Dojo, Yahoo, JSModule, etc.), we asked Kris to explain what makes modules.js different. He had some interesting things to say.

Existing Module Loaders Fall Short of Traditional Language Import Semantics

Kris started out his notes to us with an interesting point:

Ideally, you [would be able to] use import semantics similar to Java, Python, or even Perl [in JavaScript]. All [existing JavaScript module loaders] fall short in one way or another.

He then points out some ways in which modules.js meets this objective where others fail (along with an admission that some of his information about these other loaders might be a bit out-of-date):

Compared to JSModule

JSModule is the most similar [to modules.js]. It also uses XHR, eval, singleton
module cache, and scope injection. It's also lighter. In general,
modules.js is what JSModule could grow up to be. JSModule is a bit
messy; it pollutes the scope chain that it implicitly passes to its
modules with its own internal variables because it uses eval in local
scope instead of global scope (I have a fun way around this problem).
JSModule also adds itself to global scope; modules.js cleverly avoids
this. modules.js includes modules using their URL relative to the
module loader URL or the module URL if it's prefixed with a dot; this
permits easy migration and refactoring. JSModule also supports an
include path; when I explored that feature for modules.js, I
determined that searching for the script over HTTP performed very
poorly even though it provides a better approximation of how other
languages work server side.

Compared to the Dojo and Google Loaders

Dojo loader (last I checked) and Google's loader both perform strictly
asynchronous loads and piggyback one layer of dependency management on
the onLoad handler. The key difference here is that module's loaded
with modules.js can have recursive dependencies. In Dojo and Goog,
there is an important distinction between loading scripts in global
scope and in module scope. In global scope, you simply initiate an
asynchronous load of all the modules you want and attach an onLoad
observer that will be signaled when the page has loaded AND all of the
requested modules have loaded. However, onLoad may fire before all of
the modules required by your modules are loaded. To get around this,
in module scope, you have to write complicated dependency management
code to ensure that the scripts load in order: [your dependencies,
your continuation, the onload continuation]. This can be very
complicated and detracts from time spent actually writing features.

Google loader uses document.write to do script insertion which has two
advantages over modules.js: it prevents script flicker on pages with
long DOMs, and it can load cross domain scripts, which is handy if
you're loading standard libraries from their cache.

Compared to YUI Loader

YUI Loader uses a static dependency table to ensure that YUI modules
are loaded in the correct order. This means that third party modules
have to monkey patch this table if they have inter-module
dependencies. It's similar to modules.js in that it uses XHR.

A Note about Global Scope

YUI, Goog, and Dojo all evaluate modules in global scope. modules.js
protects global scope with an enclosure and provides developers with
the ability to share functions without adding them to the transitive
global scope. Instead, you add them to the module object and import
them into your imported object's scope. Nothing ever /needs/ to be
added to global scope, and developers are protected in many ways from
accidentally "sharing" variables with other modules on global scope.

In conclusion:

It's not a solution for everybody, but it's a good solution for many
people.

Frankly, the community sees a lot of new Ajax libraries written by folks who don't appear to have familiarized themselves with the state of the art before diving in. While I have respect for anyone who takes the time to contribute to the community, it's refreshing to see a craftsman at work. Nice work, Kris!

Posted by Ben Galbraith at 8:00 am
14 Comments

++++-
4 rating from 28 votes

Thursday, June 12th, 2008

Gears 0.3 Released, and Google I/O videos on Ajax related content available

Category: Ajax, GWT, Gears, Google, JavaScript, Presentation

Some good stuff came out from my employer. First, we have the Gears 0.3 release which includes support for Firefox 3! I have been using it for awhile, and it has been great. The team wanted to get it out before the Firefox 3 launch (planned for June 17th). A plugin like Gears can get deep into browser internals, so it is a challenge to keep up to date as APIs change in beta releases, so it is great to be out there now and I we will take a close look at the final release!

As well as Firefox 3 support, Gears 0.3 includes:

Then, all of the videos from Google I/O sessions have been published.

I put together a playlist that includes Ajax and Gears related content:

Check out the great talks such as:

Gears

GWT

General Ajax

Wow, a lot of material there!

Posted by Dion Almaer at 3:53 pm
7 Comments

+++--
3.9 rating from 15 votes

Tuesday, May 27th, 2008

Announcing AJAX Libraries API: Speed up your Ajax apps with Google’s infrastructure

Category: Ajax, Google, JavaScript, Library

AJAX Libraries API

I just got to announce the Google AJAX Libraries API which exists to make Ajax applications that use popular frameworks such as Prototype, Script.aculo.us, jQuery, Dojo, and MooTools faster and easier for developers.

Whenever I wrote an application that uses one of these frameworks, I would picture a user accessing my application, having 33 copies of prototype.js, and yet downloading yet another one from my site. It would make me squirm. What a waste!

At the same time, I was reading research from Steve Souders and others in the performance space that showed just how badly we are doing at providing these libraries. As developers we should setup the caching correctly so we only send that file down when absolutely necessary. We should also gzip the files to browsers that accept them. Oh, and we should probably use a minified version to get that little bit more out of the system. We should also follow the practice of versioning the files nicely. Instead, we find a lot of jquery.js files with no version, that often have little tweaks added to the end of the fils, and caching is not setup well at all so the file keeps getting sent down for no reason.

When I joined Google I realised that we could help out here. What if we hosted these files? Everyone would see some instant benefits:

  • Caching can be done correctly, and once, by us... and developers have to do nothing
  • Gzip works
  • We can serve minified versions
  • The files are hosted by Google which has a distributed CDN at various points around the world, so the files are "close" to the user
  • The servers are fast
  • By using the same URLs, if a critical mass of applications use the Google infrastructure, when someone comes to your application the file may already be loaded!
  • A subtle performance (and security) issue revolves around the headers that you send up and down. Since you are using a special domain (NOTE: not google.com!), no cookies or other verbose headers will be sent up, saving precious bytes.

This is why we have released the AJAX Libraries API. We sat down with a few of the popular open source frameworks and they were all excited about the idea, so we got to work with them, and now you have access to their great work from our servers.

Details of what we are launching

You can access the libraries in two ways, and either way we take the pain out of hosting the libraries, correctly setting cache headers, staying up to date with the most recent bug fixes, etc.

The first way to access the scripts is simply be using a standard <script src=".."> tag that points to the correct place.

For example, to load Prototype version 1.6.0.2 you would place the following in your HTML:

HTML:
  1.  
  2. <script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js"></script>
  3.  

The second way to access the scripts is via the Google AJAX API Loader's google.load() method.

Here is an example using that technique to load and use jQuery for a simple search mashup:

HTML:
  1.  
  2. <script src="http://www.google.com/jsapi"></script>
  3.   // Load jQuery
  4.   google.load("jquery", "1");
  5.  
  6.   // on page load complete, fire off a jQuery json-p query
  7.   // against Google web search
  8.   google.setOnLoadCallback(function() {
  9.     $.getJSON("http://ajax.googleapis.com/ajax/services/search/web?q=google&;v=1.0&;callback=?",
  10.  
  11.       // on search completion, process the results
  12.       function (data) {
  13.         if (data.responseDate.results &&
  14.             data.responseDate.results.length>0) {
  15.           renderResults(data.responseDate.results);
  16.         }
  17.       });
  18.     });
  19. </script>
  20.  

You will notice that the version used was just "1". This is a smart versioning feature that allows your application to specify a desired version with as much precision as it needs. By dropping version fields, you end up wild carding a field. For instance, consider a set of versions: 1.9.1, 1.8.4, 1.8.2.

Specifying a version of "1.8.2" will select the obvious version. This is because a fully specified version was used. Specifying a version of "1.8" would select version 1.8.4 since this is the highest versioned release in the 1.8 branch. For much the same reason, a request for "1" will end up loading version 1.9.1.

Note, these versioning semantics work the same way when using google.load and when using direct script urls.

By default, the JavaScript that gets sent back by the loader will be minified, if there is a version supported. Thus, for the example above we would return the minified version of jQuery. If you specifically want the raw JavaScript itself, you can add the "uncompressed" parameter like so:

JAVASCRIPT:
  1.  
  2. google.load("jquery", "1.2", {uncompressed:true});
  3.  

Today we are starting with the current versions of the library, but moving forward we will be archiving all versions from now onwards so you can be sure they are available.

For a full listing of the currently supported libraries, see the documentation.

Here I am, talking about what we are doing in two short slides:

The Future

This is just the beginning. We obviously want to add more libraries as you find them useful. Also, if you squint a little you can see how this can extend even further.

If we see good usage, we can work with browser vendors to automatically ship these libraries. Then, if they see the URLs that we use, they could auto load the libraries, even special JIT'd ones, from their local system. Thus, no network hit at all! Also, the browser could have the IP addresses for this service available, so they don't have the hit of a DNS lookup. Longer lived special browser caches for JavaScript libraries could also use these URLs.

The bottom line, and what I am really excited about, is what this could all mean for Web developers if this happens. We could be removed of the constant burden of having to re-download our standard libraries all the time. What other platform makes you do this?! Imagine if you had to download the JRE everytime you ran a Java app! If we can remove this burden, we can spend more time flushing out functionality that we need, and less time worrying about the actual download bits. I am all for lean, but there is more to life.

Acknowledgements

I want to acknowledge the other work that has been done here. Some libraries such as jQuery and Dean Edwards Base were already kind of doing this by hot linking to their Google Code project hosting repository. We thought this was great, but we wanted to make it more official, and open it up to libraries that don't use our project hosting facilities.

Also, AOL does a great job of hosting Dojo already. We recommend using them for your Dojo needs, but are proud to also offer the library. Choice is good. Finally, Yahoo! placed the YUI files on their own CDN for all to use.

Posted by Dion Almaer at 9:42 am
72 Comments

++++-
4.8 rating from 164 votes

Monday, May 5th, 2008

Ajaxian Featured Tutorial: Using YSlow for Performance Analysis

Category: Ajax, Tutorial

Kristopher William Zyp has written a post on how to use YSlow to analyze the performance of JavaScript applications.

To understand what aspects of a Web application you need to improve, you must properly analyze the components of the application. This article looks at how you can use the Firebug extension to Firefox and the YSlow add-on to instrument a Web application. After you install these tools, connect to the site that you are developing and click YSlow on the Firefox status bar. This opens the YSlow interface in Firebug. Now click the Performance button. YSlow performs an analysis of your application and provides a report on the different parts of the network transfer time of your application, as Figure 1 shows.

Most of the concepts mentioned are derived from the 10 rules defined by Yahoo! for better web application performance but Kristopher breaks down some of the concepts into examples and provides explanation on how to interpret the data. The explanation of the FireBug profiler is especially helpful to those just coming into the Ajax development space and want a better understanding of how to optimize their code:

Posted by Rey Bango at 10:14 am
2 Comments

++++-
4.7 rating from 13 votes

Wednesday, April 30th, 2008

Ajax Accessibility and ARIA

Category: Accessibility, Ajax

John Resig put together a nice overview of the ARIA Live Regions specification with an example of how you can track a list of people in a way that a screen reader can understand when someone is added or deleted. Imagine a todo list application.

HTML:
  1.  
  2. <ol aria-live="polite" aria-relevant="additions removals"
  3.     aria-describedby="users-desc" id="users">
  4.   <li>John</li>
  5.   <li>Mary</li>
  6.   <li>Ted</li>
  7.   <li>Jane</li>
  8. </ol>
  9.  
  • aria-live="polite" How polite the live area is (as in, how likely is it to butt in to what the user is currently listening to/interacting with). The default is 'polite' - in that it waits until all forms of user interaction have been completed before describing the updates to the user.
  • aria-relevant="additions removals" Only notify the user about new node additions and removals. Since we wish to provide the user with a live list of users we can expect them to be both transitioning online and offline - this will give us the appropriate level of updates to make this possible.
  • aria-describedby="users-desc" A pointer to the element that describes the contents of the live area. If the user

    wishes to know more about what the contents of the field represent this element can be read to them.

Firefox supports this right now (as of 2.0) and we covered AxsJax the toolkit that helps you implement these features, which Google Reader uses to get the job done.

Posted by Dion Almaer at 10:22 am
3 Comments

++++-
4 rating from 17 votes

Friday, April 25th, 2008

Immediate Translation and Mibbit

Category: Ajax, JavaScript, Library, Screencast

Translate Bookmarklet

I just posted on a a translate bookmarklet that uses the Google AJAX Language API:

I really liked getting the Ajax Language API out into developers hands as god knows we shouldn't have to worry about translations. Now we can use the API and have the Google back-end do all of the work.

I have recently had a couple of scenarios where I really wanted a quick translation. I had a few twitter messages pass through my stream in French and Spanish. I had the answer to some technical issues show up on foreign forums.

So, I decided to create a Translate bookmarklet that allows me to select any foreign text, click on the bookmark, and a little window pops up with the English translation if it can work it out. Automatic translation is far from perfect yet, but for many scenarios you can easily get the gist (e.g. you wouldn't want to automatically convert a book).

This is how I created the bookmarklet:

The source

First, I have the raw JavaScript source that will become the bookmarklet. There are a few sections of the code. First, we setup a method that will go off and call the Ajax Language API, passing in the translation and language that we want. This is where you would change the language code for non-English.

JAVASCRIPT:
  1.  
  2. if (!window['apiLoaded']) {
  3.   window.apiLoaded = function() {
  4.     var language = "en";
  5.     var text = window.getSelection().toString();
  6.     if (text) {
  7.       google.load("language", "1", { "callback" : function() {
  8.         google.language.detect(text, function(dresult) {
  9.