Matt Snider JavaScript Resource

Understanding JavaScript and Frameworks

Wednesday, August 29, 2007

High Performance JavaScript Video

The guys at Plaxo have developed a large and powerful web application to help you keep in touch and up-to-date. In this video “Joseph Smart” discusses what they learned while developing their JavaScript driven application. There are some really great take aways and this is a must watch:

posted by Matt Snider at 10:11 am  

Monday, August 27, 2007

5 JavaScript Frameworks

I stumbled upon this article today, while researching techniques for capturing the back button in JavaScript. This article highlights the features of 5 top-tier JavaScript frameworks:

  1. YUI
  2. Prototype
  3. Rico
  4. Qooxdoo
  5. Dojo

Justin, says Top 5, but doesn’t say what criteria he measured them by. Ignoring his ranking, these are 5 powerful Frameworks (although Rico is really an extension of the Prototype Framework). And I had not taken a look at Qooxdoo before:

Top 5 javascript frameworks

posted by Matt Snider at 2:37 pm  

Friday, August 24, 2007

Useful Object Oriented JavaScript Resources

Another Great Post by Agile Ajax:

Useful OO JavaScript resources

posted by Matt Snider at 11:15 am  

Thursday, August 23, 2007

Super Simple Image Viewer

A designer friend of mine was having trouble with one of those Image Slideshow JavaScripts you download off the internet and ask for my help. I thought it would be an easy fix, but after looking at the code I realized 2 things: the code was crap and my friend knew very little about web technologies. The code was supposed to cache images using a simple ‘addPhoto’ function and then cycle through them with a previous and next anchor without requiring page refreshes. However, all it really did was modify the URL, which would require some server-side scripting.

Being a relatively nice person, and also curious to see how difficult and time-consuming it would be to write a super-simple image slideshow using YUI I said that I would write something.

My goals were as follows:

  • unobtrusive
  • support next/prev
  • support a dynamic # of sets of image files
  • super-lightweight
  • must use module pattern

About 90 minutes of work later, the result is a 2kb minimized file that only requires ‘yahoo-dom-event.js’. A page using the slideshow need only have two anchors (with ids ‘’showNext” and “showPrev”) and an image tag (with id “image”). If you want to have more than 1 set of images then create a series of anchor tags and give them each IDs. These IDs will be used to identify the data set. Lastly, to add images to the file I created a shortcut method ‘addPhoto’ which can be used as follows:

An Example with 4 Sets of Images

//addPhoto(/*anchor ID of set*/, /*path to image file*/); addPhoto(’set1′, ‘image1-1.jpg’); addPhoto(’set1′, ‘image1-2.jpg’); addPhoto(’set1′, ‘image1-3.jpg’); addPhoto(’set2′, ‘image2-1.jpg’); addPhoto(’set2′, ‘image2-2.jpg’); addPhoto(’set2′, ‘image2-3.jpg’); addPhoto(’set3′, ‘image3-1.jpg’); addPhoto(’set3′, ‘image3-2.jpg’); addPhoto(’set3′, ‘image3-3.jpg’); addPhoto(’set4′, ‘image4-1.jpg’);

I also have a live example.

Change Made on 11/15/2007

As Jak pointed out I did not do a very good job explaining how to use this tool. In order to use this, you should first include these two files:

yahoo-dom-event.js
matts_photo_viewer.js

I suggest doing this as the last elements in your body tag:

<script type=”text/javascript” src=”http://mattsnider.com/js/yahoo-dom-event.js”></script> <script type=”text/javascript” src=”http://mattsnider.com/js/matts_photo_viewer.js”></script> <script type=”text/javascript”> // replace these with the actual names of your files addPhoto(’portfolio1′, ‘images/berserk1.jpg’); addPhoto(’portfolio1′, ‘images/berserk2.jpg’); addPhoto(’portfolio1′, ‘images/berserk3.jpg’); addPhoto(’portfolio2′, ‘images/parasite1.jpg’); addPhoto(’portfolio2′, ‘images/parasite2.jpg’); addPhoto(’portfolio2′, ‘images/parasite3.jpg’); </script> </body>

The last script tag is where you will put in your images. The first parameter in an ‘addPhoto’ Function call should be a portfolio name. If you want only one collection of images then use the same string for all ‘addPhoto’ Function calls. The second parameter is the relative path to your image. Call ‘addPhoto’ for each image you want to have in the viewer.

In your HTML markup, you will have to use 3 ID attributes: image, showNext, showPrev. The ‘image’ ID should be applied to the IMG tag that you want the update. The ’showNext’ ID should be applied to your “next” anchor tag and the ’showPrev’ to your “previous” anchor tag.

Optionally, if you want to have multiple sets (portfolios) of images, you need to attach an event handler to some element that will call

Core.Widget.PhotoViewer.changeSet(nameOfThePortfolio);

This will be one of the portfolio names you used as the first parameter in your ‘addPhoto’ Funtion calls.

posted by Matt Snider at 6:17 pm  

Tuesday, August 21, 2007

jQuery vs. Prototype from Agile Ajax

I saw this post on one of my favorite blogs, Agile Ajax. Despite the title, it is not an analysis of jQuery versus Prototype but a discussion of the OOP design of the two Frameworks. I like Brian’s analogy of Prototype being JavaScript with training wheels and other Frameworks like programming without training wheels. Using Prototype has a tendency to make coders lazy, attaching everything to the ‘this’ operating and using event and function binding all over the place, when it is not really necessary or efficient. The Module Pattern is the most efficient pattern I have used and Brian Dillard discusses this as well at the end of his article. Enjoy:

jQuery vs. Prototype: OO JavaScript with or without training wheels

posted by Matt Snider at 5:16 pm  

Sunday, August 12, 2007

YUI 2.3 Released

YUI 2.3 came out almost 2 weeks ago and I forgot to mention it. Several old feature have been improved and revisited, and 6 new feature have been added. I am most impressed by the color picker (great extension for WYSIWYG editors and theme editors), deferred image loader (allows for low res images, followed by high res versions for faster page loading), and the improved CSS package (more layouts, better normalization and fonts). Anyway, it is better than before and there are a lot more packages to include if you like.

Ultimately, though, there is only one piece that you need on every project and that is yahoo-dom-event.js. This minimized file (36k) contains the yahoo.js, dom.js, and event.js core functionality. Using this file you will have all the DOM manipulation functions that enhance productivity and one of the best event hander packages that exists today. It also, contains CustomEvent, which is my favorite part of the YUI library.

On a side note, I had dinner with Eric Miraglia of YAHOO! about a month ago and asked for some changes to the connection manager. I tend to think of AJAX requests as another event type and would like to see it incorporated with the Event package, or as a CustomEvent. This did not happen, but there has been some improvement to the ConnectionManager allowing the Object to behave more like an Event.

posted by Matt Snider at 1:22 pm  

Thursday, August 9, 2007

Continuations in JavaScript

I had heard of the term ‘Continuation’ before, but had only glanced at it and never thought about how it could apply to JavaScript. Fortunately, someone else did the thinking for me. The low-down is that the Continuation Pattern can be used when executing really slow JavaScript algorithms that lock up the browser. By doing a Continuation, you can ‘chunk’ Function algorithms into smaller processes and free up the browser so that the user isn’t stuck waiting 5 seconds for your complex JavaScript algorithm to finish. For a detailed explanation check out Marijn Haverbeke article:

http://marijn.haverbeke.nl/cps/

posted by Matt Snider at 11:08 am  

Wednesday, August 8, 2007

Safari 2.0 Regex Bug Crashes Browser

Several of my projects have reported that my JSON objects were not working properly in Safari 2.0 and less. Namely, the browser completely crashes when trying to parse the server returned JSON object. I always use Douglas Crockfords ‘Json.js‘ file to sanitize my JSON messages and could not figure out what was wrong. After some digging and some debugging on a friend’s mac, I learned that Safari does not support regular expression evaluations on data larger than ~5k. The only solution is to not sanitize the JSON in Safari browsers.

Tobie Langel also wrote a blog post about this entitled “Yet Another Safari Bug“. He is focusing on how to leverage the Prototype Framework to do this and has modified the regex to allow slightly larger data set.

I choose to do the following browser detection, because I could not find/write a non-browser detection solution that targeted only Safari and stop the browser from crashing.

if (Core.Client.browser == “Safari”) { return (jsonResponse) ? eval(jsonResponse) : []; } else { return (jsonResponse) ? jsonResponse.parseJSON() : []; }

This leverages the browser detection functions in Core.js.

Update 10/29/2007: On Saturday (10/27/2007) I spoke with Douglas Crockford at the Code Camp conference and he has found the limit to exist in Strings 5000 to 7000 characters long, depending on your machine. Unfortunately, he doesn’t plan to update JSON.js, anytime in the near future, to handle Safari 2, as the browser is being phased out.

Also, Steve @ blog.stevenlevithan.com has written a better Regex Object XRegExp 0.2. I have not spent much time working with it, but it is supposed to defeat the Safari Bug and generally improve JavaScript Regex support.

posted by Matt Snider at 2:05 pm  

Saturday, August 4, 2007

Module Pattern Template

So, as most of you know, I have been swamped with work lately. However, I promised myself that I would get you all a detailed article by the end of this week, regardless of how busy I am. In the near future I want to get back into comparing the different Frameworks, however, those articles take 5-10 hours to write and I just do not have that much time today. Instead, lets discuss the Module Pattern some more. In this article, I am going to show you my template for organizing my module patterns and discuss some details and gotchas about it.

First, why use the module pattern? The module pattern is best used with objects that are instantiated once (or very few times) per page. The module pattern does not leverage the power of prototype based OOP as the Functions are not being attached directly to the prototype of the Object. Instead you are instantiating a function and creating a closure thereby enclosing a self contain Object, which is more expensive in CPU cycles and memory when called frequently. I use the module pattern for 3 reasons, when writing: widgets, managers (like an Event Manager), and business logic for pages.

Here is an example of a module pattern that I use for managing the business logic of a page, which is the business need that I use the Module Pattern for most frequently:

Template.js

/** * Copyright (c) 2007, Matt Snider, LLC. All rights reserved. * Version: 1.0 */ /** * The PageName class manages the business logic of the PageName page * @namespace Core.Biz * @class PageName * @dependencies library */ Core.Biz.PageName = function() { // // Object namespace; private variables go here // var self = null; // internal object to reference public self // // Module dom namespace; id references to the DOM and other DOM objects go here // var dom = { }; // // Module evt namespace; event callbacks go here // var evt = { }; // // Module req namespace; AJAX request and callbacks go here // var req = { }; // // Public methods and constants // return { /** * The DOM selector class to identify example DOM elements * @property CLASS_EXAMPLE * @type String */ CLASS_EXAMPLE: ‘example’, /** * Some publicly available method */ publicDoSomething: function() { }, /** * initialize the object, put elements here that use global object elements (like static variables) */ init: function() { // initialize DOM references that are not null for (var k in dom) { if (isString(dom[k])) { dom[k] = $(dom[k]); } } self = Core.Biz.PageName; } }; }();

In this example ‘Core.Biz.PageName’ will create this object:

Core.Biz.PageName = { CLASS_EXAMPLE: String, publicDoSomething: Function, init: Function }

The object will be created when your page loads, but the internal objects that require the DOM should be put inside the ‘init’ Function and that function should be called when the document is ready (for best performance) or when window loads (if you do not use a powerful enough Event management Toolkit). Inside the closure Function, I generally create 3 namespaces (unless one is not needed), which helps me organize and manage my Object, these are: dom, evt, and req.

The ‘dom’ namespace will generally have the String IDs that I use to find elements on a page, or null, if I am going to initialize the DOM node reference through some other means in the ‘init’ Function. That namespace might look something like this:

var dom = { body: ‘projectBody’, someAnchor: ‘link1′, someOtherElem: null };

By putting this namespace first all other functions of the object can reference these elements. The ‘init’ function will automatically call document.getElementById (or equivalent depending on your Framework) on any String you defined in the namespace, so thereafter the Object members will reference DOM nodes. I would define ’someOtherElem’ in the ‘init’ Function as well, maybe by calling “dom.someOtherElem = dom.body.getElementsByTagName(’div’)[0];”.

The variable ’self’ is an internal shortcut to reference the public object. Initially ‘null’, you assign the ‘Core.Biz.PageName’ Object to it during the ‘init’ Function. Since references to ’self’ will not be evaluated until those Functions are called, it is safe to do use this Object as long as you run the ‘init’ Function first. Using ’self’ helps to prevent memory leaks or circular logic, and you do not have to worry about managing ‘this’. I also use it if I need to call an internal method that is not yet instantiated. For example you would not normally be able to access methods in the ‘req’ namespace from ‘evt’ because ‘req’ is declared after ‘evt’. However, as shown in the ‘evt’ namespace discussion below, you can circumnavigate this issue, by calling a public method on ’self’.

The ‘evt’ namespace will contain all non-trivial event callback functions for events attached to DOM nodes. These events should be attached in the ‘init’ Function after you have finished declaring your ‘dom’ namespace. If using YUI it might look something like this:

var evt = { onAnchorClicked: function(e) { var targ = YAHOO.Util.Event.element(e); CBP.publicDoSomething(); } }; … init: function() { … YAHOO.Util.Event.addListener(dom.someAnchor, ‘click’, evt.onAnchorClicked); … }

The ‘req’ namespace will contain all AJAX request and callback functions. I find this namespace helpful, because I can organize all my AJAX logic in the same place. If you do not use AJAX in your application or the Object does not manage AJAX, then omit this namespace.

The ‘init’ Function will be used to initialize elements of the Object that require the DOM. The first loop is included to do the automatic conversion of the ‘dom’ namespace ID references into DOM nodes. I then declare the ’self’ Object so that any internal references to the public Object are readily available. Thereafter, I will attach events, AJAX, and initialize other widgets used by the page. If you are using YUI I recommend the following line of code be included right after ‘Core.Biz.PageName’ is initialized to fire the ‘init’ Function as soon as the DOM is ready and before the window is completely loaded:

YAHOO.util.Event.onDOMReady(Core.Biz.PageName.init);

That about wraps things up. This is a complicated subject and if you have any questions, do not hesitate to ask. Also, I would be interested in hearing about how you organize your module pattern objects and any pointers you might have.

posted by Matt Snider at 4:26 pm  

Thursday, August 2, 2007

Ext JS 1.1 Released

The Ext team have released a new version of their Framework. I have mentioned this Framework before, because they have developed their package to support other Frameworks (such as YUI, Prototype, and Dojo). A few new features have been added, but more importantly the documentation has been greatly improved and the Framework is completely standalone, although it still supports extending other Frameworks. Find out more at Extjs.com:

Ext JS 1.1

posted by Matt Snider at 10:22 am  

Powered by WordPress