Projects
September 8th, 2005
This is the project page for my entry into the addEvent() recoding contest. It works in all of the modern browsers: Windows IE 5+, Mozilla, Opera, and Safari. The code meets every item outlined in the guideline - attempting to be as short and simple as possible. You can view a demo of it in action.
This library consists of two functions: addEvent and removeEvent. To use them, simply copy the code from below, paste it into your Javascript code, and call it using these methods:
addEvent( object, eventType, function );
The 'object' parameter should be the object upon which you want the event to be called.
The 'eventType' parameter should hold the name of the event, for example: 'click', 'mouseover', 'load', 'submit', etc. More can be found here.
The 'function' parameter should be a reference to a function that you wish to have called whenever the event fires. One parameter will be passed to 'function' - the event object.
Some examples of addEvent in use:
addEvent( document.getElementById('foo'), 'click', doSomething );
addEvent( obj, 'mouseover', function(){ alert('hello!'); } );
removeEvent( object, eventType, function );
removeEvent is virtually identical to addEvent, with the obvious difference: Instead of the function being added to the event handler, it is removed instead. All of the above code and parameters applies to this function.
The code, itself, is very short and simple - only 15 lines long:
function addEvent( obj, type, fn ) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
obj.attachEvent( 'on'+type, obj[type+fn] );
} else
obj.addEventListener( type, fn, false );
}
function removeEvent( obj, type, fn ) {
if ( obj.detachEvent ) {
obj.detachEvent( 'on'+type, obj[type+fn] );
obj[type+fn] = null;
} else
obj.removeEventListener( type, fn, false );
}
Much of the above code is trying to fix a serious problem with Internet Explorer. The code has to be this troublesome due to the fact that when your attached function gets fired, the 'this' reference refers to the worthless 'window', when, in fact, it should refer to the parent object. An explanation of the key points:
obj['e'+type+fn] = fn;
This makes the function a child of the specified object. The key, which is placed in the object hash, is (hopefully) unique and won't collide with any other function additions.
obj[type+fn] = function(){ obj['e'+type+fn]( window.event ); }
This line creates an anonymous function who, once executed, will fire the previously attached function - passing it the global event object. This whole function is being attached to the object so that it can be removed later, using the removeEvent() function.
Finally, for more information on the attachEvent, detachEvent, addEventListener, and removeEventListener functions - please refer to the excellent resource at Quirksmode.
If you have any additional questions concerning the above code, please feel free to ask.
Tags: programming, event, javascript, popular
68 Comments on 'Flexible Javascript Events'
August 30th, 2005
Lazy Sheep is a del.icio.us bookmarklet that auto-tags and auto-describes your bookmarks.
Using the tags and descriptions shared by other del.icio.us users, Lazy Sheep makes tagging a page a one-click operation. In order to best suit any user, Lazy Sheep also includes a comprehensive set of options that can be configured to your exact specifications.
Visit
Tags: javascript, bookmarklet, delicious, cool, popular
38 Comments on 'Lazy Sheep Bookmarklet'
July 10th, 2005
This is a hack that brings the power of address translation (converting a US Postal Address into a Latitude/Longitude) to the Google Maps API - something that wasn't provided in the default distribution.

View the Demo! - Download the Code
This hack, which is completely reusable, is broken down into a couple portions.
Address Translation Proxy (written in Perl)
This portion of this project queries the open API provided by Geocoder, which offers free address translation for any postal address in the United States. (If you live in Canada, you may want to check out Geocoder.ca). The code is very very simple, the only reason why it's needed is due to the fact that Javascript applications can't make queries to services that aren't on the same domain. The code is so short, I can show it here:
#!/usr/bin/perl
use CGI;
use LWP::Simple;
my $cgi = new CGI();
my $a = $cgi->param('a');
my $d = get( "http://rpc.geocoder.us/service/rest?address=$a" );
$d =~ /geo:long>([^< ]*).*?geo:lat>([^< ]*)/is;
print "Content-type: text/plain\n\n";
print "$1,$2";
The above code does the following:
It gets the address from the browser - a query which looks something like this: gaddress.cgi?a=123+Main+St+Anywhere,+NY.
A query is made to the Geocoder service provided at this URL: http://rpc.geocoder.us/service/rest
Finally, the latitude and longitude are parsed out of the results and returned to the Javascript client.
Javascript Addressing Querying
This simple function, written in Javascript, makes a query to the Address Translation Proxy asking it to convert an address into a Google GPoint. This function has two parameters that need to be taken into consideration:
function GAddress( String address, Function callback );
The first argument, address, is a string representing the address that you want to translate (for example, "123 Main St. Anywhere, NY"). The second argument, callback, is a reference to a function which will be called once the translation is complete. That function will be called with two arguments:
function callback( GPoint point, String address );
The first argument, point, will either be a GPoint representing the latitude/longitude of an address OR null, if the address does not exist. The second argument is the same address as what was sent when you called GAddress.
Now, using both of these components, it's time to wrap them together and put them to use! If you're interested to see what a final result looks like, check out this demo.
If you'd like to put this code to use, feel free to download the code below and give it a try!
- gaddress.tar.gz - Contains sample index.html, Javascript Query Function (gaddress.js), and Address Translation Proxy (gaddress.cgi). To install:
- Copy the contents of the archive to your web directory.
- Run the following command, from the command-line (or your favorite FTP client) chmod 0755 gaddress.cgi
- Go to the Google Maps API signup page and generate an API key for the URL where you uploaded the files.
- Finally, get the API key which you generated, open index.html, and change key=CHANGEME to represent your API key.
- You should be good to go! Have fun!
Tags: hacks, google, perl, popular, address, maps, geocoder, geo
78 Comments on 'Google Address Translation'
June 23rd, 2005
Using an idea grabbed from a mailing list post, I implemented the diff algorithm discussed in the following paper (free registration required):
P. Heckel, A technique for isolating differences between files
Comm. ACM, 21, (4), 264--268 (1978).
The implementation, itself, has two functions, one of which is recommended for use:
- diffString( String oldFile, String newFile )
- This method takes two strings and calculates the differences in each. The final result is the 'newFile' marked up with HTML (to signify both deletions from the oldFile and additions to the newFile).
Sample Code
document.body.innerHTML = diffString(
"The red brown fox jumped over the rolling log.",
"The brown spotted fox leaped over the rolling log"
);
Sample Output
The red brown spotted fox jumped leaped over the rolling log.
Projects Using this Code:
Downloads

This work is licensed under a Creative Commons Attribution 2.5 License.
Tags: algorithm, diff, javascript, papers, cool, popular
49 Comments on 'Javascript Diff Algorithm'
June 20th, 2005
This is my entry into the Waxy.org Automated Wikipedia Contest. There's still a number of bugs to squish, but I'm working on them. A summary of the features:
Download
- AniWiki.user.js - This is a greasemonkey script. To use, you must be using Mozilla or Firefox and have the Greasemonkey extension installed (version 0.33, minimum).
Tags: wiki, wikipedia, javascript, animation, cool, popular
9 Comments on 'AniWiki'
April 20th, 2005
This tool goes through your current Google Search History, grabs all of your recent searches and turns it into an RSS feed. Would work best set up as a nightly/hourly cron job, redirecting to a file.
This tool is written in Perl and uses a few, slick, modules: WWW::Mechanize, XML::LibXML, and XML::RSS. I was influenced by the very nice webscrape tool when building this.
A sample, from my searches, can be found here:
http://ejohn.org/apps/ghistory/google.rdf
And how it looks in my newsreader (Newsgator):

Downloads
Tags: perl, google, search, rss, popular
8 Comments on 'Google Search History RSS'
March 27th, 2005
A Greasemonkey extension that adds tag auto-complete capabilities to the traditional del.icio.us posting areas. This is a powerful extension which can greatly increase your del.icio.us posting speed. I've spent some time playing around with it, thus far, and it's been helping me out significantly.
The premise behind this extension is that it goes through your existing 'Post' page, takes the tag data from within the page and gives you auto-completion capabilites of it. This is how the current interfaces are supported:
- The traditional posting interface (Screenshot) is fully supported. Additionally, the tags are also sorted by popularity.
- The 'experimental' interface (Screenshot) is supported, but tag results are sorted alphabetically.
- The popup posting interface is currently not supported as it does not contain any tag data.
It appears that another auto-complete hack was done a while back, but no longer exists. After doing some more digging around I was able to find an implementation of that specific piece of code. Upon inspection, however, it appears as if all tag data is hard-coded into the javascript (which is highly inefficient).
Features
- Tag Auto-Completion
- Sorting by popularity (Traditional interface only).
- Tags can be completed using the right arrow, tab, enter, or escape keys.
- To view alternate tag suggestions, hit the 'up' or 'down' arrow.
Known Bugs
- Will only complete the last tag being entered (not tags in the middle of the text area).
- Sometimes if you type really fast it will complete the tag automatically.
Updates
- Version 3 (2005-03-27): Any non-space character is valid in a tag.
- Version 2 (2005-03-26): Is now capitalization agnostic. You can type in both upper and lower case and auto-complete words which are both upper and lower case.
- Version 1 (2005-03-25): Initial release.
Downloads
Tags: javascript, greasemonkey, delicious, tags, popular, cool
40 Comments on 'Del.icio.us Auto-Complete'
February 10th, 2005
This application scrapes the excellent anonymous proxy list available at Proxy 4 Free (I use to use Stay Invisible), filters them, and renders them appropriately for most applications. For example, the SwitchProxy extension to Firefox plays nicely with this.
I've made a copy of the program available for all to use, to which the query string options are:
- c = County - The country by which you want to filter the proxies by, defaults to 'United States'.
- t = Type - The type of proxies that you want, leave blank for all. Defaults to 'anon'.
Updated 2005-02-10: Requests are now cached daily. I was afraid that too many requests might upset the server owners, whom provide such an excellent service.
Updated 2005-11-16: Stay Invisible removed their free proxy lists, so I'm now using a different service that seems comparable.
Links
Downloads
Tags: perl, scrape, proxy, popular
119 Comments on 'Anonymous Proxy List'
·
« Previous entries