Object oriented programming has been around for quite some time and was made popular by C++ back in the day. Nowadays, even web scripting languages support the paradigm. JavaScript does not have true OO but allows you to use the design pattern in your code. Today, we will dive into using object oriented programming with the popular JavaScript framework Prototype.
Prototype makes it easy to declare your own objects by using the "Class.create()" method:
- var sampleObject = Class.create();
var sampleObject = Class.create();
Once you do that you can start writing your class specific methods and properties inside the "prototype" object:
- sampleObject.prototype = {
- }
sampleObject.prototype = {
}
To declare private properties you simply specify the name of the property followed by a colon and the value:
- sampleObject.prototype = {
- linkIDs: ['mainPageLink', 'cdmScreenLink', 'adminLink', 'helpLink'],
- statusMessage: '',
- currentLinkID: 'myLink'
- }
sampleObject.prototype = {
linkIDs: ['mainPageLink', 'cdmScreenLink', 'adminLink', 'helpLink'],
statusMessage: '',
currentLinkID: 'myLink'
}
The important thing to remember is that each property needs to be separated from the next by a comma. As shown above, property values can be a array, a number, a string but cannot be empty value. While:
currentLinkID: 'myLink',
is valid while
currentLinkID:,
is not.
Declaring your own functions is not any different. Before we look into functions however, there is one function that requires special attention: the "initialize" function:
- initialize: function() {
- }
initialize: function() {
}
The initialize function is what JavaScript calls automatically when you create an instance of your object. If you are familiar with OO, this function is the constructor of your object. Any setup and initial requirements for using your object should be done in here.
So to get back to regular functions, they are declared in the format functionName: function() {} as in:
- doSomething: function() {
- }
doSomething: function() {
}
So far your object should like like this:
- var sampleObject = Class.create();
- sampleObject.prototype = {
- linkIDs: ['mainPageLink', 'cdmScreenLink', 'adminLink', 'helpLink'],
- statusMessage: '',
- currentLinkID: 'myLink',
- initialize: function() {
- },
- doSomething: function() {
- }
- }
var sampleObject = Class.create();
sampleObject.prototype = {
linkIDs: ['mainPageLink', 'cdmScreenLink', 'adminLink', 'helpLink'],
statusMessage: '',
currentLinkID: 'myLink',
initialize: function() {
},
doSomething: function() {
}
}
Big deal right, including that in your html page and/or a separate JavaScript file does not do anything for you. The next step in making it of any use is to actually create an instance of the object like so:
- var sampleObjectInstance = new sampleObject();
var sampleObjectInstance = new sampleObject();
Creating an instance of the object automatically calls all your code inside the "initialize" function. Here, a good practice is to wrap the creation of your object inside the windows load or dom:loaded (Prototype v1.6) event like:
- Event.observe(window, 'load', function() {
- var sampleObjectInstance = new sampleObject();
- });
Event.observe(window, 'load', function() {
var sampleObjectInstance = new sampleObject();
});
Or
- document.observe("dom:loaded", function() {
- var sampleObjectInstance = new sampleObject();
- });
document.observe("dom:loaded", function() {
var sampleObjectInstance = new sampleObject();
});
To expand on using properties inside your object, whenever you want to access a property such as "currentLinkID", you have to prefix it with "this" as in:
- this.statusMessage = 'Who Am I?';
this.statusMessage = 'Who Am I?';
That is because inside your object's function, without "this", the code does not know about the property. The same applies to using function so you cannot simply called the "doSomething" function with:
doSomething();
but instead if you have to use:
this.doSomething();
This can get a little more complicated when it comes to using event listeners inside your code. Let me elaborate. To tie an event observer that will call the "doSomething" function when a users clicks the link with ID 'myLink', you would usually do:
- $(this.currentLinkID).observe('click', this.doSomething);
$(this.currentLinkID).observe('click', this.doSomething);
While that will work, if you try to access any class properties (such as "statusMessage") inside the "doSomething" function, you will get "undefined" for their values. That is because, again as pointed out above, the function is not aware that it belongs to an object so it does not know that the object has properties. The remedy is simple, simply append .bind(this) to the function when it is tied to the event as in:
- $(this.currentLinkID).observe('click', this.doSomething.bind(this));
$(this.currentLinkID).observe('click', this.doSomething.bind(this));
A similar approach needs to be applied when using the prototype built-in Ajax object. If you want to tie your custom functions to the "onFailure", "onComplete" or "onSuccess" functions, you need to use the "bindAsEventListener" function:
- onSuccess: this.showContent.bindAsEventListener(this)
onSuccess: this.showContent.bindAsEventListener(this)
"Bind" also needs to be used whenever you employ the "each" construct as described in Gotcha with Prototype.Bind and Arrays
Below is the full class:
- var sampleObject = Class.create();
- sampleObject.prototype = {
- linkIDs: ['mainPageLink', 'cdmScreenLink', 'adminLink', 'helpLink'],
- statusMessage: '',
- currentLinkID: 'myLink',
- initialize: function() {
- this.statusMessage = 'Who Am I?';
-
- $(this.currentLinkID).observe('click', this.doSomething.bind(this));
- },
- doSomething: function() {
- alert(this.statusMessage);
-
- new Ajax.Request(
- $(this.currentLinkID).href,
- {
- method: 'get',
- onSuccess: this.processContent.bindAsEventListener(this),
- evalScripts: true
- }
- );
- },
- processContent: function(request) {
- }
- }
-
- Event.observe(window, 'load', function() {
- var sampleObjectInstance = new sampleObject();
- });
var sampleObject = Class.create();
sampleObject.prototype = {
linkIDs: ['mainPageLink', 'cdmScreenLink', 'adminLink', 'helpLink'],
statusMessage: '',
currentLinkID: 'myLink',
initialize: function() {
this.statusMessage = 'Who Am I?';
$(this.currentLinkID).observe('click', this.doSomething.bind(this));
},
doSomething: function() {
alert(this.statusMessage);
new Ajax.Request(
$(this.currentLinkID).href,
{
method: 'get',
onSuccess: this.processContent.bindAsEventListener(this),
evalScripts: true
}
);
},
processContent: function(request) {
}
}
Event.observe(window, 'load', function() {
var sampleObjectInstance = new sampleObject();
});
To call the functions of the sampleObject from outside you would simply do:
- sampleObjectInstance.doSomething();
sampleObjectInstance.doSomething();
While you can access it's properties with the syntax:
- alert(sampleObjectInstance.statusMessage);
alert(sampleObjectInstance.statusMessage);
That concludes the basic guide to using object oriented programming with Prototype.
At a fundamental level it's important to understand how JavaScript timers work. Often times they behave unintuitively because of the single thread which they are in. Let's start by examining the three functions that we have access to with which to construct and manipulate timers.
var id = setTimeout(fn, delay); - Initiates a single timer which will call the specified function after the delay. The function returns a unique ID with which the timer can be canceled at a later time.
var id = setInterval(fn, delay); - Similar to setTimeout but continually calls the function (with a delay every time) until it is canceled.
clearInterval(id); - Accepts a timer ID (returned by either of the aforementioned functions) and stops the timer callback from occurring.
In order to understand how the timers work internally there's one important concept that needs to be explored: timer delay is not guaranteed. Since all JavaScript in a browser executes on a single thread asynchronous events (such as mouse clicks and timers) are only run when there's been an opening in the execution. This is best demonstrated with a diagram, like in the following:
 (Click to view full size diagram)
There's a lot of information in this figure to digest but understanding it completely will give you a better realization of how asynchronous JavaScript execution works. This diagram is one dimensional: vertically we have the (wall clock) time, in milliseconds. The blue boxes represent portions of JavaScript being executed. For example the first block of JavaScript executes for approximately 18ms, the mouse click block for approximately 11ms, and so on.
Since JavaScript can only ever execute one piece of code at a time (due to its single-threaded nature) each of these blocks of code are "blocking" the progress of other asynchronous events. This means that when an asynchronous event occurs (like a mouse click, a timer firing, or an XMLHttpRequest completing) it gets queued up to be executed later (how this queueing actually occurs surely varies from browser-to-browser, so consider this to be a simplification).
To start with, within the first block of JavaScript, two timers are initiated: a 10ms setTimeout and a 10ms setInterval. Due to where and when the timer was started it actually fires before we actually complete the first block of code. Note, however, that it does not execute immediately (it is incapable of doing that, because of the threading). Instead that delayed function is queued in order to be executed at the next available moment.
Additionally, within this first JavaScript block we see a mouse click occur. The JavaScript callbacks associated with this asynchronous event (we never know when a user may perform an action, thus it's consider to be asynchronous) are unable to be executed immediately thus, like the initial timer, it is queued to be executed later.
After the initial block of JavaScript finishes executing the browser immediately asks the question: What is waiting to be executed? In this case both a mouse click handler and a timer callback are waiting. The browser then picks one (the mouse click callback) and executes it immediately. The timer will wait until the next possible time, in order to execute.
Note that while mouse click handler is executing the first interval callback executes. As with the timer its handler is queued for later execution. However, note that when the interval is fired again (when the timer handler is executing) this time that handler execution is dropped. If you were to queue up all interval callbacks when a large block of code is executing the result would be a bunch of intervals executing with no delay between them, upon completion. Instead browsers tend to simply wait until no more interval handlers are queued (for the interval in question) before queuing more.
We can, in fact, see that this is the case when a third interval callback fires while the interval, itself, is executing. This shows us an important fact: Intervals don't care about what is currently executing, they will queue indiscriminately, even if it means that the time between callbacks will be sacrificed.
Finally, after the second interval callback is finished executing, we can see that there's nothing left for the JavaScript engine to execute. This means that the browser now waits for a new asynchronous event to occur. We get this at the 50ms mark when the interval fires again. This time, however, there is nothing blocking its execution, so it fires immediately.
Let's take a look at an example to better illustrate the differences between setTimeout and setInterval.
setTimeout(function(){ /* Some long block of code... */ setTimeout(arguments.callee, 10); }, 10); setInterval(function(){ /* Some long block of code... */ }, 10);
These two pieces of code may appear to be functionally equivalent, at first glance, but they are not. Notably the setTimeout code will always have at least a 10ms delay after the previous callback execution (it may end up being more, but never less) whereas the setInterval will attempt to execute a callback every 10ms regardless of when the last callback was executed.
There's a lot that we've learned here, let's recap:
- JavaScript engines only have a single thread, forcing asynchronous events to queue waiting for execution.
setTimeout and setInterval are fundamentally different in how they execute asynchronous code.
- If a timer is blocked from immediately executing it will be delayed until the next possible point of execution (which will be longer than the desired delay).
- Intervals may execute back-to-back with no delay if they take long enough to execute (longer than the specified delay).
All of this is incredibly important knowledge to build off of. Knowing how a JavaScript engine works, especially with the large number of asynchronous events that typically occur, makes for a great foundation when building an advanced piece of application code.
In this tutorial, i will be teaching you how to create a mini javascript framework. Now its not going to be anywere near as feature rich as other frameworks such as mootools and jquery but its a start.
Step 1 : Create the files
index.htm, Our html file framework.js, Our javascript file
Step 2 : Populate the index.htm file
Ok first things first, lets get some html code into our index file.
GeSHi (html4strict): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> </head> </body> </html>
Created by GeSHI 1.0.7.20
The above code is pretty self explanatory.
Now, add the link to our javascript file inbetween the head tags
GeSHi (html4strict): <script type="text/javascript" src="framework.js"></script>
Created by GeSHI 1.0.7.20
Next thing to do, add some functions from the frame work we will create. Add this after the first script tags
GeSHi (html4strict): <!-- window.onload = function() { Framework.Effects.add("box", 'blink', function() { // Functions here }); Framework.Effects.start(); } //--> </script>
Created by GeSHI 1.0.7.20
Explanation of the above:
window.onload = function() { } This tells the browser to run the code inside the function after the page has fully loaded.
Framework.Effects.add("box", 'blink', function() { // Functions here }); This is a function that we will create. It has three parameters, object id, effect type and function. The first parameter should be a string of the id for the object we want to put the effect on. The second parameter is the effect type. For this tutorial, there will only be one effect, "blink". The third and final parameter is the function. Here you put what ever code you want to run when ever the effect starts.
Framework.Effects.start(); This is another framework function that we will create. All it does is tell the browser to start the effects.
Step 3 : The framework itself
This is the longest step in the tutorial so pay attention. In this step, open up framework.js as this is the file we will be editing.
Firstly, we have to create our framework object. Put this code at the top of the page:
GeSHi (javascript): var Framework = new Object();
Created by GeSHI 1.0.7.20
This just tells the browser that the variable Framework is an object.
Next, we create our first sub-object: Styles Put this code after the framework variable.
GeSHi (javascript): Framework.Styles = { add: function(obj, styles) { for (style in styles) { obj.style[styles[style][0]] = styles[style][1]; } }, rem: function(obj, styles) { for (style in styles) { obj.style[styles[style][0]] = null; } }, get: function(obj, style) { return obj.style[style]; } };
Created by GeSHI 1.0.7.20
Now to explain it all.
Framework.Styles = {}; This creates the Styles object in the Framework object.
add: function(obj, styles) { for (style in styles) { obj.style[styles[style][0]] = styles[style][1]; } }, This is the first function in our styles object. It takes two parameters, a html object and an array. The object is simply: ... document.getElementById('objid') ...
The array format is like so:
Array { Array { 'styletype', 'styles' } }
The styletype would be a css attribute like color and the styles would be a value like #ff0000
for (style in styles) { obj.style[styles[style][0]] = styles[style][1]; } This creates a simple for loop. It works in the same way as a PHP foreach loop.
PHP
GeSHi (php): foreach ($styles as $style) {}
Created by GeSHI 1.0.7.20
Javascript
GeSHi (javascript): for (style in styles) {}
Created by GeSHI 1.0.7.20
As you can see its almost identical.
obj.style[styles[style][0]] = styles[style][1]; This gets the objects styles and then edits the styletype with the styles.
If coding this literally, it would be:
obj.style.color = "#ff0000";
rem: function(obj, styles) { for (style in styles) { obj.style[styles[style][0]] = null; } }, This does exactly the same thing except each styletype in the array is removed from the object.
get: function(obj, style) { return obj.style[style]; } Byfar the simplest function in the Styles object, this just gets the object, the style specified and returns the styles contents.
Example usage:
var object = document.getElementById("box");
// Setting the styles using the previous add function Framework.Styles.add(object, [ ['color', '#ff0000'] ]);
alert(Framework.Styles.get(object, 'color')); // Will alert, you guessed it, #ff0000
The Effects Object Now we are going to create the main effects object. This is the part the tutorial has been building up to. Here is the beast in all its glory:
GeSHi (javascript): Framework.Effects = { effects: [], timers: [], add: function(obj, type, func) { Framework.Effects.effects.push([type, obj, func]); }, blink: function(obj, func) { var obj = document.getElementById(obj); setInterval(function() { if (Framework.Styles.get(obj, 'visibility') == 'hidden') { Framework.Styles.add(obj, [['visibility', 'visible']]); } else { Framework.Styles.add(obj, [['visibility', 'hidden']]); } func(); }, 500); }, start: function() { for (effect in Framework.Effects.effects) { var effect = Framework.Effects.effects[effect]; Framework.Effects.timers[effect[0] + effect[1]] = false; switch (effect[0]) { case 'blink': Framework.Effects.blink(effect[1], effect[2]); break; } } } };
Created by GeSHI 1.0.7.20
Confusing huh? Well not to worry, I shall explain it all. Before I do, add that code under the Styles object. Now lets explain it.
Framework.Effects = {}; This creates another object just like the Styles object.
effects: [], timers: [], These are two empty arrays. Yes, thats right, arrays. You can define arrays in two ways in javascript: var array = new Array(); or var array = []; Guess which one I use.
add: function(obj, type, func) { Framework.Effects.effects.push([type, obj, func]); }, Remember when we used the add function on the HTML page? Well this is the function that gets called.
Quik Recap:
GeSHi (javascript): // This is what we wrote on the HTML page Framework.Effects.add("box", 'blink', function() { // Functions here });
Created by GeSHI 1.0.7.20
Now the first parameter is a STRING not an Object like the functions in the Styles object. There is a reason for this but I will not explain it in this tutorial. The second parameter is the effect type. Also a string. The third is the function. Now if left empty, nothing will run when the effect blink is run. If there is code in it, it will be run every time the blink effect is run.
Framework.Effects.effects.push([type, obj, func]); This just pushes a new array into the effects array we defined earlier. It contains the effect type, object id and function.
blink: function(obj, func) { var obj = document.getElementById(obj);
setInterval(function() { if (Framework.Styles.get(obj, 'visibility') == 'hidden') { Framework.Styles.add(obj, [['visibility', 'visible']]); } else { Framework.Styles.add(obj, [['visibility', 'hidden']]); } func(); }, 500); }, Here we go. Our first effect in the mini framework. It takes two parameters, object id and function.
var obj = document.getElementById(obj); This creates a new variable called obj which contains the object of the id given.
setInterval(function() { if (Framework.Styles.get(obj, 'visibility') == 'hidden') { Framework.Styles.add(obj, [['visibility', 'visible']]); } else { Framework.Styles.add(obj, [['visibility', 'hidden']]); } func(); }, 500); This is the most important part of our blink effect even though its very simple. The first part is to create an interval. Some of you may know it as setTimeout. setInterval is the samething but I prefere using it. This interval is set to run at every 500 milliseconds or every half second in simple terms.
if (Framework.Styles.get(obj, 'visibility') == 'hidden') { Framework.Styles.add(obj, [['visibility', 'visible']]); } else { Framework.Styles.add(obj, [['visibility', 'hidden']]); } Here we make use of some functions we created in the Styles object. The if statement uses the get function in the Styles object to check the value of the objects visibility style. If its hidden, use the add function to make the visibility visible else make it hidden again. This will just loop over and over so you get the blink effect.
func(); Now this is the function that we put as the third parameter on the index page. Remember?
Quik Recap:
GeSHi (javascript): // This is what we wrote on the HTML page Framework.Effects.add("box", 'blink', function() { // This is the third parameter // Functions here });
Created by GeSHI 1.0.7.20
Because it was passed through a variable, to run the function inside, all we have to do is put brackets at the end. Neat huh?
start: function() { for (effect in Framework.Effects.effects) { var effect = Framework.Effects.effects[effect]; Framework.Effects.timers[effect[0] + effect[1]] = false; switch (effect[0]) { case 'blink': Framework.Effects.blink(effect[1], effect[2]); break; } } } Yay, the final function in the Effects frame work. I am happy because its 2:45am and I am very tired. Now we create a function called start. We ran it once on the index page.
Quik Recap:
GeSHi (javascript): window.onload = function() { Framework.Effects.add("box", 'blink', function(){}); // Here we go Framework.Effects.start(); }
Created by GeSHI 1.0.7.20
This function makes it all work. It goes through the effects array we looked at in the add function, gets the effect type and sends the appropriate information to the appropriate effects functions.
for (effect in Framework.Effects.effects) { var effect = Framework.Effects.effects[effect]; Framework.Effects.timers[effect[0] + effect[1]] = false; switch (effect[0]) { case 'blink': Framework.Effects.blink(effect[1], effect[2]); break; } } Here we have another for loop. Same type as the one I explained earlier.
Quik Recap:
PHP foreach ($styles as $style) {}
Javascript for (style in styles) {}
This for loop gets all the effect arrays in the effects variable. var effect = Framework.Effects.effects[effect]; The effect variable now contains this iterations array contents.
Framework.Effects.timers[effect[0] + effect[1]] = false; Because this is not needed in this framework for this tutorial, I will not explain it. Leave it in there though as it will be needed for future parts to this tutorial.
switch (effect[0]) { case 'blink': Framework.Effects.blink(effect[1], effect[2]); break; } Here we have a simple switch statement. Works in the same way as a PHP switch statement. For those of you who dont know what a switch statement is, think of it like this:
switch (variable) { case "a": alert("a"); break;
case "b": alert("b"); break;
case "c": alert("c"); break;
default: alert("Unknown letter"); break; }
IS
if (variable == "a") { alert("a"); } else if (variable == "b") { alert("b"); } else if (variable == "c") { alert("c"); } else { alert("Unknown letter"); }
The switch statement simply gets the effect type and sends the object id and function to the particular effect.
And there you have it. An introduction to a simple javascript mini effects framework. I hope you have learned alot from this tutorial.
You see it in Google search results and a lot of other sites that have good search functionality. When you perform a search, your words or phrases are highlighted in the search results making it easy for you to find the most relevant content.
Today I’m going to show you a simple way to add this to your website or blog so your users can find what they need in style. I think that this kind of thing should be implemented more often for how easy it is to implement.
Here we go!
The JavaScript code:
-
function highlightOnLoad() {
-
-
if (/s\=/.test(window.location.search)) {
-
var searchString = getSearchString();
-
-
var textContainerNode = document.getElementById("content");
-
-
var regex = new RegExp(">([^<]*)?("+searchString+")([^>]*)?<","ig");
-
highlightTextNodes(textContainerNode, regex);
-
}
-
}
-
-
-
function getSearchString() {
-
-
var rawSearchString = window.location.search.replace(/[a-zA-Z0-9\?\&\=\%\#]+s\=(\w+)(\&.*)?/,"$1");
-
-
return rawSearchString.replace(/\+/g,"\|");
-
}
-
-
function highlightTextNodes(element, regex) {
-
var tempinnerHTML = element.innerHTML;
-
-
element.innerHTML = tempinnerHTML.replace(regex,">$1<span class='highlighted'>$2</span>$3<");
-
}
-
-
-
addOnLoad(highlightOnLoad()); function highlightOnLoad() {
// Get search string
if (/s\=/.test(window.location.search)) {
var searchString = getSearchString();
// Starting node, parent to all nodes you want to search
var textContainerNode = document.getElementById("content");
// The regex is the secret, it prevents text within tag declarations to be affected
var regex = new RegExp(">([^<]*)?("+searchString+")([^>]*)?<","ig");
highlightTextNodes(textContainerNode, regex);
}
}
// Pull the search string out of the URL
function getSearchString() {
// Return sanitized search string if it exists
var rawSearchString = window.location.search.replace(/[a-zA-Z0-9\?\&\=\%\#]+s\=(\w+)(\&.*)?/,"$1");
// Replace '+' with '|' for regex
return rawSearchString.replace(/\+/g,"\|");
}
function highlightTextNodes(element, regex) {
var tempinnerHTML = element.innerHTML;
// Do regex replace
element.innerHTML = tempinnerHTML.replace(regex,">$1<span class='highlighted'>$2</span>$3<");
}
// Call this onload, I recommend using the function defined at: http://untruths.org/technology/javascript-windowonload/
addOnLoad(highlightOnLoad());
Now, the CSS:
-
span.highlighted {
-
background-color: #161616;
-
font-weight: bold;
-
} span.highlighted {
background-color: #161616;
font-weight: bold;
}
Code explanation
First, the highlightOnLoad function checks window.location.search to see if we need to be running any of this stuff, then calls getSearchString to get a sanitized search string so that nothing funky can happen if, say, the user searches for ‘<script>’. You should really be sanitizing all search inputs at least on the back-end anyway.
Then, the highlightTextNodes function uses a regex replace on our textContainerNode’s innerHTML. The regex verifies that the text is between a > and a < (and not the other way around). Actually nice and simple!
Caveats
This may end up being a bit slow if you are doing this on a LOT of text, but for my blog text, it seems quite snappy to me. Also, the CSS does not bold text inside links, but the background color is there to make it obvious.
Bramus introduces a new version of jsProgressBarHandler with bugfix to making multiple barImages properly work with Safari and addition of an internal queue.

jsProgressBarHandler is a Javascript based Percentage Bar / Progress Bar, inspired upon JS-code by WebAppers and CSS-code by Bare Naked App. Next to a structural rewrite of the WebAppers code, this javascript progress bar can easily be extended and tweaked just by setting a few parameters.
jsProgressBarHandler has been tested and verified working in IE6, IE7, FireFox 2 and Safari 3.0.3. Other browsers should work fine too (untested though).
This is one of the coolest javascript progress bars I’ve ever seen. You can find non-ajax demo here and a bit less cool Ajax demo here.

A long awaited Prototype cheat sheet - a full reference to a bleeding edge 1.6.0.2 is finally here. I had no experience creating something like this before, so any bugs or suggestions are very much appreciated. Couple of notes about notations:
- Modules are sorted in a somewhat logical order - those commonly used are mostly in the left/center area, while deprecated/utility methods are all the way to the right
- Method can be recognized by parentheses following it (anything that doesn’t have ones is a property)
- Deprecated items are marked red and have NO parentheses/arguments specified
- Prototype extends quite few native objects’ prototypes with a set of convenient methods. In such cases there’s an explicit note about it next to a module name - i.g.
stripScripts() method from “String (String.prototype)” can be called as 'foo'.stripScripts()
- When a module is also a class, there’s a “(constructor)” note next to it - i.g. “Hash (constructor)” means that it should be called as
new Hash()
- There are few bonus items (such as those from Prototype.Browser) which are not yet included in documentation
Download and Enjoy!
Update:
I have managed to choose the most retarded format for the cheat sheet - almost squared - which was impossible to print or navigate. Sincere apologies.
There is an updated version at the same address which also fixes few other annoyances:
- Ajax.Responders is now a separate section
- Added missing Event.fire
- Added Prototype.BrowserFeatures.XPath
- Added simple “Dimensions/Offsets” diagram
- Minor rearrangements
Dates are sometimes needed in forms a webdeveloper includes in his work. And users always try to input the date in a format which is not the right one. Date pickers can be very helpful and also eye-candy
JavaScript Libraries in particular have grown immensely in popularity, and the article continues to be a great resource. However, it was apparent from how the Web development community responded, that there was a single missing component. Designers and developers wanted an at-a-glance comparison chart. I considered how to go about researching and writing such a comparison, and shortly thereafter, I was contacted by Cody Lindley. He let me know that he'd been working on such a chart. Here is that chart.
| |
|
DOM Assistant 2.5 |
YUI 2.4.1 |
jQuery 1.2 |
Dojo 1.0 |
Prototype 1.6 |
EXT 2.0 |
Mootools 1.11 |
| 1 |
Official (complete!) documentation (API found on domain) |
 |
|
|
|
|
|
|
| 2 |
Official off-line documentation (off-line API found on domain, included in download, and managed by Dev. team) |
 |
|
|
|
|
|
|
| 3 |
Real code, with working live examples included in the API (not just demo's/tutorials out side of the API) |
 |
|
|
|
|
|
|
| 4 |
An official manual/book, not an API, not tutorials, but a manual/book online or hardcopy |
 |
 |
 |
 |
 |
 |
 |
| 5 |
Official real world demos included in download |
 |
 |
 |
 |
 |
 |
 |
| 6 |
Modular by design (one file by design, or multiple) |
 |
|
|
|
|
|
|
| 7 |
File size (KB) not minified, obfuscated, or gzip (? = depends upon what you include) |
41.4 |
29 - ? |
77.4 |
219 - ? |
121 |
29 - ? |
9k - ? |
| 8 |
Official minified version (removing just comments and spaces) |
 |
6 - ? |
44.6 |
|
|
7 - ? |
|
| 9 |
Official packed/obfuscated version |
21 |
|
26.2 |
50 - ? |
|
|
|
| 10 |
Official hosted minified version with gzip (free, unlimited) |
 |
|
|
|
|
|
|
| 11 |
Official widgets/UI toolkit |
 |
|
|
|
|
|
|
| 12 |
SVN/CVS access |
 |
|
|
|
|
|
|
| 13 |
Unit tested |
 |
|
|
|
|
|
|
| 14 |
Public unit testing |
 |
|
|
|
|
|
|
| 15 |
Open development |
 |
|
|
|
|
|
|
| 16 |
100% Funded development (paid, full-time developers, only focus) |
 |
 |
 |
 |
 |
 |
 |
| 17 |
Official forum |
 |
|
|
|
|
|
|
| 18 |
Official Mailing list |
 |
 |
 |
 |
 |
 |
 |
| 19 |
Commercial support and training |
 |
|
|
|
|
|
|
| |
|
DOM Assistant |
YUI 2.4.1 |
jQuery 1.2 |
Dojo 1.0 |
Prototype 1.6 |
EXT 2.0 |
Mootools 1.11 |
| 20 |
Official plug-in architecture (was the base code designed and documented (documentation key) to facilitate open plug-in development by the community) Similar to modular, but with a different intent. |
 |
|
|
|
|
|
|
| 21 |
License type |
GNU |
BSD |
GPL / MIT |
AFL / BSD |
MIT |
LGPL |
MIT |
| 22 |
Free for Commercial use |
 |
|
|
|
|
|
|
| |
Official support for Safari 1.3+ |
 |
 |
 |
 |
 |
 |
 |
| |
Official support for Safari 2+ |
 |
|
|
|
|
|
|
| |
Official suppor for Safari 3+ |
 |
 |
 |
 |
 |
 |
 |
| |
Official support for Opera 8+ Mac/Win |
 |
 |
 |
 |
 |
 |
 |
| |
Official support for Opera 9+ Mac/Win |
 |
|
|
|
|
|
|
| |
Official support for Firefox Mac/Win 1.5+ |
 |
|
|
|
|
|
|
| |
Official support for Firefox Mac/Win 2.0+ |
 |
|
|
|
|
|
|
| |
Official support for IE 7 |
 |
|
|
|
|
|
|
| |
Official support for IE 6 |
 |
|
|
|
|
|
|
| |
Official support for IE 5.5 |
 |
 |
 |
 |
 |
 |
 |
| |
Official support for IE 5.0 |
 |
 |
 |
 |
 |
 |
 |
There are several factors to consider when compiling the necessary information for this comparison. The first, and most important, is terminology. Even though there are numerous features and functionalities for each JavaScript library that are similar, they do not always fit neatly into predetermined headings. It remains imperative that each library feature be weighted while keeping this in mind, and when appropriate, read the full description that accompanies each heading. This is a fantastic starting point for your own research and analysis.
Although the groundwork has been laid, another factor to consider is that there is still the effort to maintain an accurate comparison. Remember, this is a living document, and you should use the chart whenever you begin a new project that requires a library. After listening to developers who have used these libraries, we intend to make updates, modifications, and maybe even a major overhaul. The intent is to facilitate discussion, and to be the primary (most accurate) resource for determining which framework is right for you, and right for the task you need to accomplish.
Before the initial release, several of the programmers who are responsible for the creation of these libraries were contacted, and their opinions will always be taken into consideration. This helps us to maintain a balanced, unbiased opinion. The number of options available to developers today can be daunting, and helping you to choose the right tool should be done without any preconceived notions on our part. We will not always be able to guarantee that each of the creators of these libraries agree on our comparison criteria, but we will always take the steps necessary to listen and cooperate.
The final consideration is determining which libraries to include for comparison. This is a little easier to determine, since the decision is driven from a set of closed questions. Is the library licensed under an open-source license? Is there API documentation, and how often is it updated? How mature is the library, and how often are updates released? Is this a core library, or is it an extension/add-on/plugin to an existing library? These are not the only questions to ask, but they are a few that can help with the process of elimination.
Taken From: TechDune

Internet Explorer has cool add-ons which make the job of website designers and developers much easier. Here is my list of 20+ excellent Firefox add-ons that every web developer and designer should know about.
Internet Explorer Developer Toolbar Variety of tools for quickly creating, understanding, and troubleshooting Web pages.
IE Watch Allows you to view and analyze HTTP/HTTPS headers, Cookies, GET queries and POST data.
IE Web Developer Allows you to inspect and edit the live HTML DOM, evaluate expressions and display error messages, explore source code of Web page and monitor DHTML Event and HTTP Traffic.
IESpy Allows one to inspect or manipulate the DOM of any IE Web browser control.
DebugBar Brings new services to surfers and professionals. Surfers: zoom, direct Web search, e-mail page screenshots, and color picker. Developers: view HTML code, cookies, JavaScript, HTTP/HTTPS headers, and miscellaneous information.
Virtual Machine Allows you to view java applets on Web pages.
Microsoft Fiddler Logs all HTTP traffic between your computer and the Internet.
Tangram Xtml Designer Visual designer for IE Band Object, activeX Control and .NET user control.
Http Watch HttpWatch shows you HTTP and HTTPS traffic from within IE allowing you to quickly debug, fix and optimize your Web site.
Embedded Web Browser The package contains all the programmer need to extend the development of a Web browser.
CGToolbar Must have tool for CG Artists, Animators, VFX and 3d professionals.
Site Studio 6 Build rich content Web sites, with no HTML skills required.
Haptek Player An ActiveX control and Netscape Navigator Plugin that allows any webpage or application (with ActiveX support) to include Haptek’s Autonomous characters.
Flash2X Flash Hunter Save Flash movies from web pages.
iOpus iMacros Check the same sites every day,data upload, online marketing and functional testing and regression testing Web sites:
Telerik RadToolBar A flexible component for implementation of tool and button strips, needed in most web applications.
UltraEdit-32 Powerful Text, HEX, HTML, PHP and Programmer’s Editor.
Bytescout Post2Blog Freeware powerful blog editor for WordPress, Typepad, MovableType and other blogs.
Search Monster Free Flash Web Directory & Internet Search Engine is the Flash-remoting Web directory instant content for you Web site.
Zend Studio Encompasses all the development components necessary for the full PHP application.
DbaBar Integrated toolbar enabling Oracle Database Administrators to browse their databases from within Internet Explorer within minutes after installation.
Explorer Toolbar Maker lets you create your own Explorer bar from any HTML page, picture, Macromedia Flash file, or Microsoft Office document.
Dynamically Loading JS Libraries And Detecting When They're Loaded:
Sometimes it makes sense to dynamically load JavaScript library code only at the point at which it's required. If functionality which uses that library is used rarely then it makes little sense incur the overhead of an additional HTTP request or data transfer on page load.
We can dynamically load any JavaScript and add it to the document with the following function.
Making a dynamic request
function loadScript(sScriptSrc) {
var oHead = document.getElementById('head')[0];
var oScript = document.createElement('script');
oScript.type = 'text/javascript';
oScript.src = sScriptSrc;
oHead.appendChild(oScript);
}
This approach isn't without problems though. The request will load asynchronously which means that any JavaScript which depends on code returned by the request may continue to run before the request completes resulting in errors.
Callback event handlers
As described in far greater detail in JavaScript Madness: Dynamic Script Loading browsers provide the ability to specify a callback function to run once the script load completes. In most it's as simple as assigning a callback function to the script.onload event handler.
oScript.onload = callback;
Internet Explorer, as in so many cases, does things differently. It supports a onreadystatechange event handler to which we can assign a callback function. It's slightly more complicated than that used by other browsers as one has to check a return status before running the callback.
oScript.onreadystatechange = function() {
if (this.readyState == 'complete') {
callback();
}
}
Combining the parts gives us:
function loadScript(sScriptSrc, oCallback) {
var oHead = document.getElementById('head')[0];
var oScript = document.createElement('script');
oScript.type = 'text/javascript';
oScript.src = sScriptSrc;
// most browsers
oScript.onload = oCallback;
// IE 6 & 7
oScript.onreadystatechange = function() {
if (this.readyState == 'complete') {
oCallback();
}
}
oHead.appendChild(oScript);
}
Detecting script load with timeouts
Reading a number of sources however it seems that there is a lack of trust in the cross browser robustness of these event handlers. One could instead use timeouts to poll for the existence of required functions returned by the script request and run our callback once detected.
I wrote the following function to achieve just this recently. The function takes two main parameters, a string representing the function to poll for and a reference to the callback function to run once it's found.
function onFunctionAvailable(sMethod, oCallback, oObject, bScope) {
if (typeof(eval(sMethod)) === 'function') {
bScope ? oCallback.call(oObject) : oCallback(oObject);
} else {
setTimeout(function () {
onFunctionAvailable(sMethod, oCallback, oObject, bScope);
}), 50
}
}
Two additional parameters allow one to define the scope of "this" within the callback function.
The hardest part of this function was working out how to detect the existence of a function from a string.
|