- We design and build extraordinary applications for companies looking to make the next great idea a reality.
- learn more
Using Bookmarklets to Disruptive Effect
But any big change is more likely to result if there is a disruptive event such as new technologies or platforms that have a surprising effect on market share. -- Trip Hawkins
My consulting company is relatively small, so I love disruptive technologies. I see them as opportunities to sneak up on the big boys. I suppose that if I were one of the big boys, I wouldn't be so enthusiastic about disruptive technology. But there it is. Bookmarklets and Greasmonkey are just such disruptive technologies. They let you create mashups and manipulate pages in ways that were not intended by the original authors. They are a way to make content and sites work better for you.
While Greasemonkey lets you automatically execute scripts after page has loaded and allows you to make XHR requests to other domains, it requires a user to install a plug-in that isn't easily available for all browsers. Bookmarklets, on the other hand, are as easy to install as a bookmark, but they require a user to click or select a bookmark in order to work.
Last time, we saw how to load additional JavaScript into the browser in order to exceed the size limits of the bookmarklet itself. This time we're going to hack the front page of the New York Times with our own news. First, we need a bookmarklet that will load our actual script. We simply adapt our code from last time to load our nyt.js script.
javascript:(function(){var s,d=document,a=function(o){d.body.appendChild(o)};s=d.createElement('script');s.type='text/javascript';s.src='http://labs.pathf.com/bm101/nyt.js';a(s)})();
The code simply inserts a script element that points to our JavaScript file. You can see the live link below.
Drag the following link to your toolbar or bookmark it:
NYT Hack
If you now navigate to the New York Times home page and click on the link, you should be able to see some stories about Iraq inserted above the fold.
How did I do this? Well, it's all about what I packed into that nyt.js file. What's in there? Well, first I added in JQuery, my favorite Javascript library of the moment. Since the New York Times site doesn't use Prototype or anything that declares a $ function, we don't have to take any special precautions. Next, I defined a utility function to load in a script from a URL:
// NYT Funcs
var NYTHack = new Object();
NYTHack.addScript = function(url) { var scr = document.createElement("script"); scr.type = "text/javascript"; scr.src = url; $("body").append(scr);}
This is the same trick as earlier. Instead of performing an XHR, we inject Javascript which is executed withing the context of the current page. And what do we inject?
NYTHack.insertYahooNews = function() { // insert the yahoo news script tag with a callback NYTHack.addScript('http://api.search.yahoo.com/NewsSearchService/V1/newsSearch?appid=YahooDemo&query=iraq&results=5&language=en&output=json&callback=NYTHack.callBack');}
// run me$(document).ready(function(){ NYTHack.insertYahooNews();});
We load from Yahoo's News Search Service. Why Yahoo? Because they let you specify JSON as the output format and further specify a callback function, to which the JSON object is passed as a parameter. Our callback (along with a utility function) looks as follows:
NYTHack.buildStories = function(div, json) { var stories = json.ResultSet.Result; for (var i = 0; i < stories.length; i++) { div.innerHTML += '<h4><a href="' + stories[i].Url + '">' + stories[i].Title + '</a></h4><p>' + stories[i].Summary + '</p>'; }}
NYTHack.callBack = function(json) { var div = document.createElement("div"); div.id = 'nythack'; div.style.border='1px solid #ff0000'; div.style.padding='5px'; var hl = document.createElement("h2"); hl.innerHTML = "Iraq News from Yahoo!"; div.appendChild(hl); NYTHack.buildStories(div, json); $("#mainTable").before(div);}
Nothing fancy. We just pull titles, summaries and url's out of the JSON object and construct a set of headlines and links. Then we insert it ahead of the main content section of the NYT home page.
Now we don't do any error checking and you can run this bookmarklet in other pages than the NYT home page. Adding those in wouldn't have been too onerous, but it would have distracted from the main focus of the bookmarklet and cluttered the code. Ideally we would check in the bookmarklet itself to see whether we had already loaded it once by looking for a hidden div element with a particular id.
Next time we will actually use the information on the page to drive what our bookmarklet does and we will use the site itself as a web service using Sarissa.
Topics: Ajax Examples, BJAX
Comments: 3 so far
Leave a comment
About Pathfinder
Recent
- Dealing With A Legacy
- Big Changes Underway at LinkedIn for Groups
- Four blatant iPhone usability blunders (and one constant annoyance)
- Flash/Flex physics engines and examples
- A Rails Story, Or An Engine That Really Could
- Data visualization and the art of conveying information
- What’s In Your Junk Drawer?
- Selling Git on the Business End
- IE8 Beta 2 Released
- Faster JavaScript for Firefox 3.1 Thru JIT
Archives
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006



Great post! I’ve been seeing a couple people use jQuery for bookmarklets lately, not a bad idea. Keep up the great work!
Comment by John Resig, Wednesday, October 4, 2006 @ 4:22 am
That is awesome / sick! Seriously, I am in awe at the sweet hack. Any word on the support across browsers?
Comment by Chris Anderson, Tuesday, January 2, 2007 @ 11:36 pm
Yes,John Resig, I know that at least Opera supports userjs (greasemonkey) and bookmarklets. I think Safari does as well.
Comment by Jadd, Thursday, June 7, 2007 @ 5:31 am