Best practices: Posts

Mootools Beginner’s Example

If you are new to javascript or Mootools, you should:
1) Read the docs
2) Read the Mootools Tutorial

Now, the problem with the Tutorial is that it shows you snippets of how Mootools work, but doesn’t put them all together to show you how to actually do things on a page.

So in an effort to help people see the right way to write code (well, at least how I write code; “right” is definitely subjective with javascript), as well as how to use the accordion and things like Fx.Slide, I’ve authored a simple little page that demonstrates these things and comments them line by line.

So:

3) View the source of the Mootools Beginner’s Example

DomReady, DomPolling, and window.onload revisited

Via Ajaxian is this post revising the age-old window.onload problem. I tried to write a dom polling method that would re-evaluate the dom every few milliseconds maybe 3 or 4 months ago but got distracted. Here’s the work of smarter and less easily distracted people than I, and it’s worth reading (even if you skip to the end). Maybe we’ll work this into Mootools.

Peter Michaux has written a detailed post on the window.onload problem:

The goal of unobtrusive JavaScript programming it to separate the JavaScript behavior from from the HTML content and is analogous to the goal of unobtrusive CSS design to separate the CSS presentation from the HTML content. Separation of presentation and content has been possible for years but there is one wrinkle standing in the way of completely separating the behavior. This article is about previously suggested techniques to enable this separation, their problems and a new option that combines the strengths of the current techniques with an extra bonus into a new robust solution.

| Read the rest »

How to avoid parsing all the links on a page

There are a lot of different reasons to parse all the links on a page. Lightbox (and it's Mootools counterpart, Slimbox) look through all the links to find the ones that need their magic. SmoothScroll loops through them to find all the links with in-page name anchors. Here at CNET, we're starting to use javascript to insert our tracking logic into our links (instead of hard-coding them in the links in our templates).

For a page like one on CNET, this can mean having the browser iterate through document.links several times, and the result can really bog down a page.

I ran this code on cnet's home page:

JavaScript:
$A(document.links).each(function(lnk, index){
    $(lnk).addEvent('click', function(){
        alert('hi');
    });
});

drag to resize


There are 332 links on the page, and this code took 190ms. Now, I could optimize this loop, but this is probably how someone who wasn't working on optimize it might write it. For instance, using $$('a') is actually twice is fast as $A(document.links).

Anyway, the problem is when you start adding these things up. If you solve this "I need to check all the links here" problem by iterating through, you might end up slowing the page down by half a second, which is when things start getting noticeable.

In a recent post on Ajaxian, I was directed to this article on using capture to steal the event. Using this method of adding events, you can add an event listener to the whole document.body. Then, on click, evaluate your code. If the link clicked meets your criteria, execute your code, else, follow the link.

Note that IE doesn't use capturing, but I think you can still stop the event from propagating. I need to do some testing first.

Efficient Looping in Javascript

Bas Wenneker, on his blog solutoire.com just posted some data he compiled using various methods for iterating over a data set that's pretty interesting.

While I’m a great fan of Javascript Libraries like Prototype and Mootools, I’m less happy with their iterators. Iterating through a large array just takes ages using Array.each(). I think the most annoying thing with Javascript is that it freezes the browser while it’s being processed. So I started Aptana and wrote a small benchmark, and I tested it with FF2, Opera 9.1 and IE6. I did the testing on WinXP SP2 running on my crappy AMD Duron 1600 (yes, it’s almost antique). In this article I present the results of the benchmark.

See the results »

The Javascript Environmentalist

There's a nice article over at Snook's today on writing clean, concise, and reusable javascript.

As a JavaScript developer, you are in many ways an environmentalist. JavaScript is a language unlike most other languages. For when it comes to JavaScript development, we must consider the mantra of the environmentalist: Reduce, reuse, recycle.

It's a short article that's worth reading. All of these concepts are in use in our new framework, and if you're writing javascript for yourself or for CNET or whatever, it's always good to keep these things in mind.

Beware: object = object has a pitfall

So I spent an entire day discovering a quirk about javascript that I must now share. In a previous post on creating default settings for classes/objects I discussed the following technique:

JavaScript:
var Widget = new Class({
    initialize: function(element, options){
        this.element = element;
        this.options = Object.extend({
            offsetX: 0,
            offsetY: 0
        }, options || {});
        this.setPosition();
    },
    setPosition: function(){
        this.element.setStyles({
            left: this.options.offsetX + 'px',
            top: this.options.offsetY + 'px'
        });
    }
});

drag to resize


Now, this isn't a very useful class, but it illustrates the technique. The functions in our class don't have to worry if the options are defined; they are either what the default value is or they are what the user passed in. If the user elects to just pass in a subset of the values, that's fine:

JavaScript:
var myWidget = new Widget(myElement, {offsetX: 100});
//myElement will be offset by 100 on the left,
//zero (the default) on the top

drag to resize


But what if you want to extend the functionality of your class later? What if you want to be able to insert more default options?

Here's what I was doing that caused me trouble: | Read the rest »

Performace posts - CNAMES, compression, concatenation

So I've been very busy the last few weeks. I'm rewriting, well, pretty much all the javascript on Download.com. Fun! I've written a few new classes that I think will be helpful; more on those later.

In the mean time, here are two posts from Ajaxian that are worth a read. The first is on using CNAMES to allow your browser to serially download javascript and css, while the other is on compressing and concatenating files.

Note that Firebug 1 (beta) will let you actually see firefox download all your files and see the order and time each took.

Also note that our new framework environment does the compressing and concatenation stuff, but it's still interesting to see the work that others are doing.

Aaron

Back Button Support: Safari and Speed

via Ajaxian:

Daniel Kantor has implemented a Back button solution in Streampad and has shared it with us.

One of the main gripes against AJAX webapps is how they break the back button in a typical browser. There have been a few solutions (notably Brad Neuberg’s Really Simple History) but none have got it working in Safari. GMail still does not have a working back button in Safari.

They say the third time is the charm and I have tried to get a Back button thing in Streampad twice before. I do not want to use someone else’s library as they are usually more complex than I need and I did not want to put something in place until I had Safari working. I tried a few different techniques, but when I got it working in Safari, it would break in Firefox or IE.

I finally figured out a way to get this working in Firefox, IE and Safari.

While Daniel struggled with this, he found that the back button support caused a slow down in the entire app performance. He came up with a new solution that didn't suffer from the performance issues:

The general concept is this: You load a page into an iframe that calls parent.goBack() and then changes its own location to a new page (a blank page will do). Because the page jumps to a new location, it now has a history. If you click the back button, it will load the page again (calling parent.goBack()) and then spring forward to the dummy blank page.

JavaScript:
var historyArray = Array(); // create an empty array to hold the history
var historyCounter = -1; // initialize the array pointer to -1

function historyAdd(f){
  if (historyCounter == -1){  // the first time this is called it will change the iframe location
  document.getElementById(’hFrame’).src = “/historySpring.php”;
}

var o = historyArray[historyCounter];
if (f != o){ // don’t put in consecutive duplicates
  historyCounter++
  historyArray[historyCounter] = f; // add function to history
}

function goBack() {
  if (historyCounter> 0){ // don’t want to call it if there is nothing in history array
    historyCounter– // set the pointer back one
    var f = historyArray[historyCounter]; // get the function from the history array
    f = f+”()”;
    eval(f); // call the function
  }
}

drag to resize


this.options - setting defaults that can be overwritten in your classes

Here's a trick I learned from Valerio (author of Mootools) on how to handle options for classes and functions. After refactoring a couple of legacy scripts I thought I'd share for those of you who might not know it already. This example below uses the Mootools syntax for class creation, but the rest of it can be used even on its own I think. | Read the rest »

Optimizing Page Load Time

via ajaxian (as usual):

Aaron Hopkins of Google has released an article on Optimizing Page Load Time which came out of his experience optimizing page load times for a high-profile Ajax application.

He starts off talking about "how much I could reduce latency due to external objects. Specifically, I looked into how the HTTP client implementation in common browsers and characteristics of common Internet connections affect page load time for pages with many small objects." | Read the rest »

Categories

Archives

Links and whatnot