Activate your free membership today | Log-in

Tuesday, November 20th, 2007

How To Build A Read/Write JavaScript API

Category: Articles, JavaScript

Rakesh Pai has written up a piece on GData JavaScript client library (video), CrossSafe, and SubSpace.

He discusses the high level, and then delves into the requirements and process for getting cross domain code working:

Here’s what you require to get cross-domain read write JavaScript APIs to work.

  • The “setup” required at the client’s end is that he should have at least one static cacheable resource embedded in the page where he’s consuming the API, which is loaded from the same domain as his page. This could be in the form of a static CSS file, or an image. If the page doesn’t have either, it will be required to insert one – maybe in the form of a 1px image hidden away by using inline style attributes. This is usually not too much to ask for, considering that pages are either made up of spacer GIFs or CSS documents, usually loaded from within the same domain. The static resources I mentioned could even be from a different sub-domain within the same domain, but it might complicate scripts slightly to have it set up that way. If this setup is not possible at all (oh, come on!), you could still find a work around2, but I think that this is the easiest way to get things up and running.

  • You will need to do some setup at your end, if you are the creator of the API. In particular, you will need to setup a “proxy” page that intercepts the requests from the JavaScript client API, conditions the data, and passes it along to the REST API. This proxy page also reads the response from the REST API, conditions the data to suit the client, and flushes it down to the JavaScript.

Now, let’s go over the process of actually orchestrating the communication.

  1. The API client library is included on the page by means of a script tag pointing to your domain (your domain being the host of the client library). This is similar to including the Google Maps API on the page.

  2. Once included, the script scans the page for the static resource mentioned above. This is done by walking the DOM looking for link or img tags, and checking the value of the href/src attribute to ensure it lies within the same domain as the calling page. The URL of this resource is stored for use later. At this point, if required, the client library can signal to the developer that it is ready for communication with the server. If the resource is not found, the client-library should throw an error and terminate.

  3. When a request requires to be made, the client library takes the request parameters and prepares the markup for a form. This form can have any method attribute value, and should have it’s action attribute set to the proxy page on your domain. The parameters to be sent to the server should be enumerated as hidden fields within the form. The client library also specifies the resource (in a RESTful sense) that needs to be acted upon. Also, the name of the static resource we had hunted down earlier is passed on to the server. This form is not appended to the document yet. This markup is then wrapped into <html> and <body> tags. The body tag should have onload=”document.forms[0].submit();”.

  4. The client library then creates a 0px x 0px iframe, without setting the src attribute, and appends it to the page’s DOM. This makes the browser think that the iframe exists in the same domain as the calling page. Then, by using the iframe document object’s open(), write() and close() methods the markup created in the previous step is dumped into the iframe. As soon as the close method is called, the form gets submitted to the proxy page on your domain because of the onload in the body tag. Also note that this gives the server access to any cookies it might have created from within it’s domain, letting you do things like authentication. In this way one part of the communication is complete, and the data has been sent to the server across domains. However, the iframe’s document.domain has now switched to point to your domain. The browser’s security model now prevents any script access to most parts of the iframe.

  5. The proxy page sitting on your server now queries your REST API – basically doing it’s thing – and gets the response. Response in hand, the proxy is now ready to flush the response to the client.

  6. If the response is rather large in size, as might be the case with a huge GET call for instance, the proxy breaks it up into chunks of not more than say 1.5 kb2.

  7. The proxy is now ready to flush the response. The response consists of iframes – one iframe for each of these 1.5 kb chunks. The iframe’s src attribute is set to the static resource we had discovered earlier. It is for exactly this purpose that we had hunted the resource down and passed on the URL to the server. At the end of each of these URLs, the proxy appends one of the chunks of the response, after a “#” symbol, so that it works as a URL fragment identifier. Also, the iframe tags are each given a name attribute, so that the client script can locate them.

  8. Meanwhile, the client-side code is where it had left off at the end of step 4 above. The script then starts polling the iframe it created to check for the existance of child iframes. This check of iframes will need to based on the iframe name the server will be sending down. It will look something like this: window.frames[0].frames[“grandChildIframeName”]. Since the static resource we have loaded into the grandchild iframe is of the same domain as the parent page, the parent page now has access to it, even the intermediate iframe is of a different domain.

  9. The client script now reads the src attributes of the iframe, isolates the URL fragments (iframe.location.hash), and reassembles the data. This data would typically be some JSON string. This JSON can then be eval’d and passed on to a success handler. This completes the down-stream communication from the server to the client, again across domains.

  10. With the entire process complete, the client-library can now perform some cleanup actions, and destroy the child iframe it created. Though leaving the iframe around is not a problem, it is not necessary and simply adds to junk lying around in the DOM. It’s best to get rid of it.

Posted by Dion Almaer at 8:46 am
13 Comments

++---
2.2 rating from 59 votes

Wednesday, November 14th, 2007

Dissecting Dijit: Dojo Widgets

Category: Articles, Component, Dojo

One of the best parts of Dojo 1.0 has been how often the team has been blogging of all things. It has been great!

Mike Wilcox has posted about Dijit, the widget platform for Dojo 1.0.

His piece covers dojo.parser, dojo.declare, the widget markup, the lifecycle of widgets, and more. Great stuff.

The lifecycle is very thorough:

preamble()
Originating in dojo.declare, preamble is a new Dojo Core feature. It’s a pre-constructor accessory. By analogy, preamble is to constructor as postMixInProperties is to postCreate. Since preamble gets the same arguments as the constructor, you may extend another object, and jump in front of the constructor and change the arguments.
constructor()
Originating in dojo.declare, constructor has a new usage pattern. Previously, it fired last, which I didn’t find particularly useful nor accurate. It now fires early in the widget lifecycle, allowing early initialization with the arguments passed into the object. While more common in use, it’s not exactly necessary, as Dijit handles the job of converting your arguments into object properties.
postMixInProperties()
Originating in dijit._Widget, postMixInProperties is used more commonly by widget developers. That said, some of its duties are superseded by the addition of constructor and preamble. Its main purpose is firing after the properties have been set, but before the widget has been parsed and created. Pre-creation work on widget properties is typically done in this method.
postCreate()
Originating in dijit._Widget, postCreate is the “heavy lifter” of Dijit. This fires after creation, but before the widget is rendered to the page. At this time in the widget lifecycle, you have access to the widget’s nodes, so additional parsing, connections, styling, or even attaching more widgets is possible.
startup()
Originating in dijit._Widget, startup is somewhat misunderstood. startup doesn’t fire unless the widget is a child of another widget. And then it only fires after it, and all of its siblings have been created. Then they all fire together.

Posted by Dion Almaer at 11:17 am
1 Comment

++---
2.9 rating from 57 votes

Friday, November 9th, 2007

Pseudo-custom events in Prototype 1.6

Category: Articles, Examples, JavaScript, Prototype

Andrew Dupont has written a tutorial on how to normalize proprietary browser events using Prototype's new custom events feature.

The piece is interesting as it talks about how the Prototype core team originally went down the wrong path trying to boil the ocean with great features that were a bit too much. And then:

we refocused, trimmed the fat, and added a whole bunch of features to the event system while still excluding thie kitchen sink. We picked some low-hanging fruit; for instance, we normalized the event object so that properties like target exist in all browsers, and we ensured events fire in the scope of the element in IE (so that this refers to the proper thing).

But we also added cross-browser support for custom events. Now developers can fire their own events alongside native browser events and can listen for both types with the same API. Custom events will make Prototype add-ons at least 50% more righteous, allowing for even more control than the standard callback pattern. Imagine TableKit firing an event when a cell gets edited, or PWC firing an event when a dialog is resized.

Since the 1.6 RC1 release, several people have asked whether we have any plans to add native support for mouseenter, mouseleave, or mousewheel. I think we ought not, lest the event codebase become an unholy thicket of special-casing. That’s the sort of environment where bugs thrive.

But, as Sam points out, the addition of custom events makes it easy for third parties to add their own support for proprietary browser events. To demonstrate, today we’ll write 20 lines of code to add sane, cross-browser support for mouse wheel events.

I’m calling these pseudo-custom events because they serve the same purpose as standard browser events: they report on certain occurrences in the UI. Here we’re using custom events to act as uniform façades to inconsistently-implemented events. Together we’ll write some code to generate mouse:wheel events. At the end of this article, you’ll know enough to be able to write code to generate mouse:enter and mouse:leave events document-wide.

This leads you into the example itself which takes you through a number of iterations before ending up with:

JAVASCRIPT:
  1.  
  2. (function() {
  3.   function wheel(event) {
  4.     var realDelta;
  5.  
  6.     // normalize the delta
  7.     if (event.wheelDelta) // IE & Opera
  8.       realDelta = event.wheelDelta / 120;
  9.     else if (event.detail) // W3C
  10.       realDelta = -event.detail / 3;
  11.  
  12.     if (!realDelta) return;
  13.  
  14.     var customEvent = event.element().fire("mouse:wheel", {
  15.      delta: realDelta });
  16.     if (customEvent.stopped) event.stop();
  17.   }
  18.  
  19.  document.observe("mousewheel",     wheel);
  20.  document.observe("DOMMouseScroll", wheel);
  21. })();
  22.  

Posted by Dion Almaer at 11:35 am
2 Comments

++++-
4.1 rating from 42 votes

Monday, November 5th, 2007

URI Comparison Functions

Category: Articles, IE

It is nice to see a post on IEBlog that isn't about ES4 ;) Dave Risney provides just that as he details the perils of comparing URIs, a common cause for security exploits and errors in general.

Investigating URI parsing related issues in various products, I’ve run across many instances of code erroneously attempting to compare two URIs for equality. In some cases the author writes their own comparison and seems to be unaware of URI semantics and in other cases the author delegates to a Windows provided function that doesn’t quite work for the author’s scenario. In this blog post I’ll describe some of the unmanaged URI comparison functions available to Win32 developers, and a few common mistakes to avoid.

The latest URI RFC 3986 does an excellent job of describing a ladder of URI comparisons. The range on the ladder trades off comparison speed for number of false negatives. False negative in this case means that the URI comparison function says two URIs are not equivalent when they are.  However, nowhere on the ladder will a comparison generate a false positive. That is, a URI comparison function should never incorrectly report that two URIs are equivalent.

To summarize, IUri::IsEqual is a good Scheme-Based Normalization URI comparison function, UrlCompare and CoInternetCompareUrl should be avoided for fear of security bugs, and with no better choices a simple case sensitive string comparison will suffice.

Posted by Dion Almaer at 7:30 am
18 Comments

++---
2.3 rating from 6 votes

Wednesday, October 31st, 2007

Transitioning from Java Classes to JavaScript Prototypes

Category: Articles, Examples, JavaScript

To class or not to class, that has been a question than many developers have faced as they came from class based OO worlds into the Prototype Oriented world of JavaScript. Much pain has endured for those that try to contort it.

Peter Michaux has detailed transitioning from Java Classes to JavaScript prototypes by looking at the Observer/Observable pattern and showing various implementations in Java and JavaScript ending up with his favourite mixin-able solution:

JAVASCRIPT:
  1.  
  2. var observablize;
  3.  
  4. (function() {
  5.  
  6.     var observable = {
  7.  
  8.       addObserver: function(observer) {
  9.           if (!this.observers) {
  10.               this.observers = [];
  11.           }
  12.           this.observers.push(observer);
  13.       },
  14.  
  15.       notifyObservers: function() {
  16.           for (var i=0; i<this.observers.length; i++) {
  17.               this.observers[i].update();
  18.           }
  19.       }
  20.      
  21.     };
  22.    
  23.     observablize = function (subject) {
  24.         for (var p in observable) {
  25.             subject[p] = observable[p];
  26.         }
  27.     }
  28.    
  29. })();
  30.  
  31. // ---------------------------
  32.  
  33. function WeatherModel() {}
  34.  
  35. observablize(WeatherModel.prototype);
  36.  
  37. WeatherModel.prototype.setTemperature = function(temp) {
  38.     this.temp = temp;
  39.     this.notifyObservers();
  40. };
  41.  
  42. WeatherModel.prototype.getTemperature = function() {
  43.     return this.temp;
  44. };
  45.  
  46. // ---------------------------
  47.  
  48. function CurrentConditionsView(model) {
  49.     this.model = model;
  50.     model.addObserver(this);
  51. }
  52.  
  53. CurrentConditionsView.prototype.update = function() {
  54.     alert(this.model.getTemperature());
  55. };
  56.  
  57. // ---------------------------
  58.  
  59. var victoriaWeather = new WeatherModel();
  60. var victoriaNews = new CurrentConditionsView(victoriaWeather);
  61.  
  62. victoriaWeather.setTemperature(15.3);
  63. victoriaWeather.setTemperature(17.0);
  64. victoriaWeather.setTemperature(14.7);
  65.  

Posted by Dion Almaer at 8:40 am
1 Comment

+++--
3.2 rating from 21 votes

Monday, October 22nd, 2007

Ajax Javascript Galleries, Slideshows and Effects Redux

Category: Ajax, Articles, UI

Max Kiesler has been doing some nice roundup posts recently. He just published Ajax Javascript Galleries, Slideshows and Effects Redux, a piece that goes through a large group of libraries and apps that show off image related functionality.

He ends up discussing:

Posted by Dion Almaer at 6:30 am
7 Comments

++++-
4 rating from 312 votes

Wednesday, October 17th, 2007

Dealing with the Flexibility of JavaScript

Category: Articles, JavaScript

Neil Roberts has written a piece on Dealing with the Flexibility of JavaScript which delves into functions that are overloaded based on signature.

For example:

JAVASCRIPT:
  1.  
  2. connect = function(/*...*/){
  3.   if(arguments.length == 1){
  4.     var ao = arguments[0];
  5.   }else{
  6.     var ao = interpolateArgs(arguments, true);
  7.   }
  8.   if(isString(ao.srcFunc) && (ao.srcFunc.toLowerCase() == "onkey")){
  9.     // ...
  10.   }
  11.   if(isArray(ao.srcObj) && ao.srcObj!=""){
  12.     // ...
  13.   }
  14. }
  15.  

Commentors on the story had varied opinions.

Isabelle likes bridges:

JAVASCRIPT:
  1.  
  2. function clicked(event){ processById(event.target.id); }
  3. function processById(id){ }
  4.  

Simon Willison and Dylan Schieman discussed how jQuery and Dojo do different things depending on not only arguments, but even the contents of strings that were passed in.

Posted by Dion Almaer at 7:47 am
6 Comments

++---
2.1 rating from 28 votes

Thursday, October 11th, 2007

Inheritance is evil, and must be destroyed: part 1

Category: Articles

When we wrote about Bernard Sumption's Animator.js there was a lot of "interest" in Bernies position that OO inheritance sucks.

Bernie decided to fuel the fire and expanded his thoughts, explaining how the strategy pattern is in fact your saviour ;)

All of the pain caused by inheritance can be traced back to the fact that inheritance forces 'is-a' rather than 'has-a' relationships. If class R2Unit extends Droid, then a R2Unit is-a Droid. If class Jedi contains an instance variable of type Lightsabre, then a Jedi has-a Lightsabre.

The difference between is-a and has-a relationships is well known and a fundamental part of OOAD, but what is less well known is that almost every is-a relationship would be better off re-articulated as a has-a relationship.

The article takes the world of Jedi and then writes a real example using Balls and BouncingBalls. He also explains why he thinks that Flash's DisplayObject hierarchy is good, and that EventDispatcher is bad.

Posted by Dion Almaer at 10:10 am
15 Comments

+++--
3.3 rating from 31 votes

Friday, October 5th, 2007

Load Balancing in your Ajax code

Category: Articles

Voxlite

Lei Zhu developed a Flash site called Voxlite that allows you to send video messages to people. The application uses both Amazon S3 and EC2, and Lei decided to do load balancing between instances on the client side itself.

He wrote up his thoughts on Client Side Load Balancing for Web 2.0 Applications, and wants your comments.

His article discusses:

  • Information on to build a sample Client Side Load Balancing
  • Comparing Server Side Load Balancing to Client Side Load Balancing
  • How an actual Web 2.0 application is using Client Side Load Balancing to achieve reliability and scability
  • How to take advantage of Client Side Load Balancing with Amazon's EC2 and S3 service.

Posted by Dion Almaer at 6:15 am
5 Comments

+++--
3.3 rating from 38 votes

Thursday, October 4th, 2007

A simple guide to using Firebug

Category: Articles, Utility

Phil Rees has written up a nice introduction to Firebug, showing us how you can use Firebug to:

  • Inspect custom stylesheets included by Google Mashup Editor
  • Modify in-memory stylesheets to see the changes reflected immediately
  • Place watches and breakpoints into running JavaScript
  • Execute arbitrary JavaScript in the context of your running application
  • Monitor Ajax calls, showing response times, posted content, and results
  • Profile JavaScript functions to help you identify bottlenecks and optimize your application.

The article walks through all of these points using Phil's DanceMaps mashup using the Google Mashup Editor.

Posted by Dion Almaer at 5:49 am
Comment here

+++--
3.9 rating from 25 votes

Monday, September 17th, 2007

Douglas Crockford’s Elements of JavaScript Style

Category: Articles, JavaScript

Douglas Crockford micro-blogged it best:

I have been at Yahoo for two years. One of the first things I did when I got there was to do a View Source of the front page. That gave me a lot of visibility into how things were done. I also saw some things to improve. That inspired me to write the first two chapters of The Elements of JavaScript Style. Part One. Part Two.

He explains through example, the following:

  • Avoid archaic constructions.
  • Always use blocks in structured statements.
  • Avoid assignment expressions.
  • Use object augmentation.
  • Use common libraries.
  • Watch out for type coercion when using ==.
  • Use the ?: operator to select one of two values.
  • Never use implicit global variables.
  • Do not use the ?: operator to select one of two actions.
  • Use the || operator to specify a default value.
  • Global variables are evil.
  • Use inner functions to avoid global variables.

What's your style?

Posted by Dion Almaer at 7:54 am
17 Comments

+++--
3.9 rating from 32 votes

Thursday, September 6th, 2007

Web Developers, Where Are We Now?

Category: Articles, Browsers

Alex Russell isn't known for holding back his opinions. He continues his tradition of calling issues to our attention in his piece on Where are we now?.

This article takes a look back to his posting, 1.5 years ago, on the state of things at that point.... and what he would like to see. He isn't happy with the progress made in the year and a half since.

He hits out at Microsoft's secretive behaviour:

The “worst case scenario” that I’ve described to folks in private for a long time is that IE 7 is the end of the line. The last hurrah. The final gasp of life in Trident’s creaking limbs. IE 7 could either signal the beginning of a renewed commitment to the web by Microsoft, or it could be the minimum MSFT can get away with to prevent customer mutiny. To assuage the latter scenario, I’ve directly and firmly asked every member of the IE team I’ve talked to since then to outline in public Microsoft’s commitment to new versions of IE. We need to see timelines, feature targets, and distribution plans for those releases as well. This might seem like putting the cart before the horse but I think it’s not too much to ask. In fact, it might even be the minimum the web development community should expect.

and he compares it to the other browser vendors:

Brendan Eich has an entire blog dedicated to communicating outward about the features that we can expect from the web as delivered by Firefox (and the platform behind it). The IE Team’s blog is eerily silent on the future of what is still the most important browser on the internet. We’re reduced to getting information from third parties and conference talks. The features planned for Firefox 3 are impressive and the work is being done in the open, meaning it’s easy to have confidence that not only will Mozilla ship what they say they will, it’ll be here when they say it will. Same goes for the excellent work the Safari team has been doing. Even Opera keeps its community on fire by shipping regular updates, showing tech previews at conferences, and blogging about the progress being made on many fronts. If the IE team is holed up working on something stonkingly good, they certainly aren’t doing themselves any favors by not telling us about it. The result of their radio silence isn’t mystery, it’s distrust. Deep, divisive, troubling distrust of the kind you can only get when folks who break up stop talking altogether.

Then, the future:

I’m pretty sure the IE team isn’t sitting still. Chris Wilson is heading up the HTML 5 working group and there’s reports of some real progress there. HTML 5 is the most important web spec under consideration anywhere so this is truly good news. But it hasn’t yet been accompanied by the kinds of communication that allow us to trust MSFT as a custodian of the web’s future.

Getting IE 7 and watching it ramp up among IE’s installed base has been good, but it’s only half the answer. The web needs to know, unequivocally, when we can expect more information about IE.Next, what OSes it will target, and what standards, improvements, and major fixes are on the roadmap even if they slip. Without that much honesty, this relationship probably won’t get off the ground again.

Are you as worried about the future as Alex?

Posted by Dion Almaer at 10:16 am
46 Comments

+++++
1.1363636363633E+197 rating from 176 votes

Wednesday, September 5th, 2007

Gears Case Study: What we learned from Remember The Milk

Category: Articles, Gears, Google, Offline, Showcase

As I posted on the Google Gears Blog:

Omar Kilani of Remember The Milk took the time to write up his teams experience in Taking web applications offline with Google Gears.

The article moves past an introduction to delve into the design decisions around an offline-capable architecture, and user messaging and presentation of state. We learn why Omar decided to go with the explicit offline mode, and then the five steps to offline conversion:

  • Ensuring resources are available offline
  • Decoupling the application from the network
  • Persisting data on the client
  • Re-creating application state from persisted data
  • Developing a synchronization strategy.
  • There is a lot to learn here.

    From their architecture considerations:

    RTM was designed as a client-side application from inception. The server-side portion of RTM is mainly used as a "dumb" data store, and the application periodically synchronizes with the server. In this case, using Gears to provide offline access was a natural fit, and was relatively quick to implement as we had some prior experience with data synchronization protocols.

    There were some features of the online experience that could not be carried over to the offline mode. One of these was the Google Maps integration, in which users can geolocate their tasks and quickly visualize where their tasks are occurring in the real world. As Google Maps requires access to Google servers to fetch map tiles and data, and such a data set is quite large and thus hard to cache, this functionality is disabled once the user enters offline mode.

    The undo feature of RTM is also unavailable in the offline version as this is a complex server-side operation (due to the multi-user nature of RTM and the ability to share tasks and lists). Instead, the user is presented with a dialog box asking for confirmation if they execute a destructive action such as delete. Undo functionality in offline mode is on the RTM roadmap, however.

    To the decisions they made on showing the user information on whether they are online or offline:

    A fundamental design decision is whether to implement offline support as "modal" or "modeless." Choosing which style to implement will, in most cases, be dictated by the type of data the application works with and how much of that data will be available offline. One style is not necessarily superior to the other, and, for example, it's much easier to implement a modeless style for tasks (in RTM) than it is for feed items (in Google Reader) based on the size of data items and the total data set alone.

    Finally, we learn some tips and caveats from the RTM Gears implementation, including dealing with the LocalServer, the different types of offline, defensive coding, debugging, and coding with upgrades in mind.

    Omar Kilani wraps it up in his conclusion:

    By now, you should be itching to add offline support to your web application (we hope!). If you should take anything away from this article, it's that taking your application offline isn't as hard or complex as it may first seem, and that Gears is a joy to work with (and it'll become even easier and more fun as the project matures and is used by more applications).

    As for us at RTM, we couldn't be happier with Gears. The speed at which we were able to provide offline functionality (four days from reading the documentation to a launchable implementation) is a testament to the quality, ease of use, and production-readiness of Gears. Many thanks to the Google Gears engineers for their foresight and for making this an open source project to which members of the Internet community can contribute.

    Thanks to the Remember The Milk team for taking their application offline in record speed, and for taking the time to share their experience.

Posted by Dion Almaer at 9:15 am
5 Comments

++++-
4.5 rating from 15 votes

Friday, August 31st, 2007

TrimPath Junction: A walk through

Category: Articles, Gears, JavaScript

Jack Herrington and Steve Yen have put together a nice little article introducing TrimPath Junction:

Junction is an all JavaScript framework that closely models the Ruby on Rails model-view-controller design pattern and implementation. And with the help of the Helma JavaScript web server, it runs the same code both on the client and on the server. Exactly the same code, in fact.

The framework not only handles the basics of rendering pages (using JavaScript templating), but it also handles data and code synchronization with the server, local client caching using Google Gears, model versioning, and much more. It's an amazingly complete solution for an entirely new model of web development.

The article walks through the building of a very simple contact management system, and shows that ONLamp doesn't believe in Long Pages ;)

Posted by Dion Almaer at 5:45 am
4 Comments

++++-
4.3 rating from 9 votes

Wednesday, August 15th, 2007

Lazy Function Definition Pattern

Category: Articles, JavaScript

Peter Michaux has written about the Lazy Function Definition Pattern.

His article takes you down the path of implementing a simple problem:

Write a function foo that returns a Date object that holds the time that foo was first called.

After critiquing 3 iterations he ends up with:

JAVASCRIPT:
  1.  
  2. var foo = function() {
  3.     var t = new Date();
  4.     foo = function() {
  5.         return t;
  6.     };
  7.     return foo();
  8. };
  9.  

He then uses the technique to implement getScrollX, and to talk about how you can use defineGetter in certain browsers to simulate lazy definition for properties that aren’t functions.

Posted by Dion Almaer at 7:08 am
27 Comments

++---
2.7 rating from 59 votes

Wednesday, August 1st, 2007

Keybindings in Web Browsers

Category: Articles

Marc Englund of IT Mill has done a study on Keybindings in Web browsers and how compatible they all are:

Modern browsers do provide built-in ways to navigate web-pages with the keyboard, but usually you have to use multiple keystrokes to get to a link or button, before you can 'click' it - and although some browsers actually assign keybindings automatically, the browser simply can not know what would be a good keybinding for a specific function. And even worse: if the page changes, the keybindings might change - and they probably will.

This is of course unacceptable for web applications - imagine a secretary using a word-processor with keybindings that might change depending on the content of the document...

The problem with keybindings on the web is mostly a multiple platform problem; your users might be using one of several operation systems, with different utility-applications installed, running various browsers, and using different keyboard layouts.

Keybindings in Web Browsers

Posted by Dion Almaer at 1:28 am
14 Comments

++++-
4.6 rating from 21 votes

« Previous PageNext Page »