Matt Snider JavaScript Resource

Understanding JavaScript and Frameworks

Friday, September 28, 2007

Xbrowser Event Handling

On of the most powerful features of almost every Framework is x-browser Event management. This is important because standards dictate that you SHOULD ALWAYS separate implementation from design by leveraging the JavaScript DOM event management, instead of writing events inline. The problem arises from the browser wars, when the yahoos over at Microsoft decided to come up with a non-standard event model, making x-browser event management painful. Each Framework has their own implementation that wraps the two event systems, sometimes including additional bells and whistles, such as: scope adjustment, deferred loading, caching, cleanup, custom events, and more. However, the event management system of most Frameworks is so complex you have to wonder if it is all necessary and how coders managed events before Frameworks.

The reality is that most people do not need the extras, just a couple simple event handler functions that wrap the x-browser methods. Many programmers do not yet understand the power of the JavaScript event handlers. Therefore, often when I give advice to new coders and ask them how they handle x-browser events, I am usually greeted with blank stares. Most beginners do not take the time to fully understand JavaScript, because it is so simple to pick up and start working with. Plus, searching the net only overwhelms one with nearly endless examples of crap code, by people who also did not take the time to properly understand JavaScript and/or good design principles.

As I said at the beginning of this article, “You SHOULD be using JavaScript event handlers, instead of writing events inline.” Managing events is not all that complex, when you only need a plain interface wrapping the x-browser methods (just annoying). Here is the simplest way to manage events:

var attachFunc = ”, detachFunc = ”; // Create the Event Function wrappers if (window.addEventListener) { // standards compliant method attachFunc = function(el, eType, fn, capture) { el.addEventListener(eType, fn, (capture)); }; detachFunc = function (el, eType, fn, capture) { el.removeEventListener(eType, fn, capture); }; } else if (window.attachEvent) { // microsoft compliant method attachFunc = function(el, eType, fn, capture) { el.attachEvent(”on” + eType, fn, capture); }; detachFunc = function (el, eType, fn, capture) { el.detachEvent(”on” + eType, fn, capture); }; } else { // event handlers unsupported attachFunc = function() {}; detachFunc = function() {}; }

This code sample will attach the appropriate event handling function to attachFunc and the appropraite event removal function to detachFunc. Put this anywhere in your code library before you start attaching events and it will simplify event management. I recommend you wrap this function into a namespace, such as “Event”, but you can use them as is. So anytime you want to attach an event (”click”, “keydown”, etc.) to an element, instead of writing something like “<a href=”#” id=”myAnchor” onclick=”someFunction();”>clickMe</a>”, you would write the following directly in your JavaScript code:

var link = document.getElementById(”myAnchor”); attachFunc(link, ‘click’, someFunction);

You can safely ignore the capture option, unless you know what the capture phase is.

For some more information on x-browser event support, check out Peter Paul Koch’s article: Advanced Event Registration.

posted by Matt Snider at 10:44 am  

Wednesday, September 26, 2007

JavaScript Style Guides

http://blogs.pathf.com/agileajax/2007/09/javascript-styl.html

Brian Dillard composed a list of different style-guides, which are more a list of best practices and coding conventions. Most of the article isn’t all that relevant. If you jump to the bottom you’ll find the following list of style guides:

There is a lot to read and these articles are somewhat dense, but if you find the time to read and understand them, you will only become a better JavaScript developer.

posted by Matt Snider at 5:36 pm  

Wednesday, September 26, 2007

CSS Frameworks And Removing X-browser Variations

There is a lot of hype on the web right now around CSS Frameworks; a lot like there used to be around JavaScript Frameworks, before they became so popular. It is important to understand what they are and why they will (or will not) be helpful to you.

What is a CSS Framework

“[A CSS Framework is] a set of tools, libraries, conventions, and best practices that attempt to abstract routine tasks into generic modules that can be reused. The goal here is to allow the designer or developer to focus on tasks that are unique to a given project, rather than reinventing the wheel each time around.” [Framework For Designers, by Jeff Croft]

That is a lofty goal and I believe that most CSS Frameworks endeavor to simplify your life. However, I do not think they usually do. Where CSS Frameworks excel is normalizing styles, especially x-browser variations and typography. Where they fail (or become cumbersome) is when they try to do too much such as: every layout under the sun, rigid design, large code-bases (bloating), etc. If a Framework does too much, then you end up needing to learn what it is doing and why, and without prolific commenting CSS can quickly become confusing and you wonder why a particular property might be necessary.

Despite the downsides, I recommend using a Framework, or at least part of a Framework. The most important effect from using a Framework is reseting browser specific styles, so that 1 stylesheet can be used for all browsers, instead of 1 stylesheet for each browser (or worse, a bunch of browser specific hacks). Most commonly, the browser variations are the default ways they apply padding, margins, and/or fonts to elements.

I personally, never use a complete Framework, because I prefer to have control over my layout and typography, but I always use a CSS Framework to reset browser styles. If you are not a designer and need a quick solution, or find CSS Frameworks helpful, then you should leverage them. Here are the few that I modeled my “reset.css” stylesheet from, which I use as a foundation for all my projects (and hopefully, on this blog as soon as I get some free-time):

  • Tripoli: tries to remain simple by mostly just resetting styles, but also applies some optimal changes to typography and layout
  • YAML: very well documented, multi-column layout builder with all the bells and whistles
  • YUI : lots of layout variety and optimized for integration with the YUI JavaScript Library

Smashing Magazine also wrote a great article about this topic where they cover more details about each CSS Framework listed here, and several others.

Normally, I would probably taut how much I like what YUI has done, but not this time. Although, I do really like their “reset.css”, I find the rest of the Framework to be heavy-handed, with too many options and not enough documentation. Also, the Framework includes styles for some parts of the JS Framework that I do not use. YAML, does a great job, but has a lot of options and extra features that you probably won’t leverage. Tripoli, has the simplest and most unobtrusive styles, and if I was to just to throw a Framework onto a site without modifying it, I would use this one.

In the end I just wanted a set of styles to reset browser specific formatting, and I modeled this by looking at the afore mentioned Frameworks:

/** * Copyright (c) 2007, Matt Snider, LLC. All rights reserved. * version: 1.0.0 */ /* remove default element padding */ body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td { margin: 0; padding: 0; } /* default color scheme */ html body { background: #fff; color: #000; } /* remove borders and possible underlining */ a, img, a img, iframe, form, fieldset, abbr, acronym, object, applet { border: none; font-variant: normal; } /* remove stylized font-variations */ address, caption, cite, code, dfn, em, strong, th, var, i, b { font-style: normal; font-weight: normal; } /* table and center elements should always be top left aligned */ caption, th, td, center { text-align: left; vertical-align: top; } q:before, q:after { content: ”; } /* remove cellpadding and cellspacing */ table { border-collapse: collapse; border-spacing: 0; } /* clear possible list-styles; should override in design */ ul, ol, dir, menu, li { list-style: none; } /* clear possible heading styles; should override in design */ h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: normal; } /* prevent default browser coloring of links */ a { color: inherit; } /* reset position of sup and sub */ sup, sub { vertical-align: text-top; } /* clear form field font settings */ input, textarea, select { font-family: inherit; font-size: inherit; font-weight: inherit; }

This is available for download at http://www.mattsnider.com/assets/css/reset.css.

What does this have to do with JavaScript

JavaScript and CSS are closely linked, especially when you consider animation and all the times you have to apply a style on the fly. It is important for JavaScript developers to understand CSS and it is also important that when they apply a style to an element, that element behaves as expected in all browsers. This blog will continue to focus on JavaScript, but every couple weeks, I will write a something important about CSS so we address more complex issues and widgets involving CSS and JavaScript.

posted by Matt Snider at 12:03 am  

Sunday, September 23, 2007

YUI JavaScript/CSS Compressor

I finally had some time/need to explore a new JavaScript compressor and had been hearing good things about the YUI compressor, so I took a look at it. The YUI compressor not only compresses (slightly better than JSMin) but claims to do some safe obfuscation. Altogether it claims to save an additional 18% over JSMin (5-10% over rhino), which is about what I experienced in my testing today. That is a substantial savings when your project uses over 200kb of JavaScript, such as Mint. I am pleased to say that I have now, not only met my 250kb library file goal, but surpassed it by another 30kb, by only switching my compression technology.

YUI compressor is a JAVA jar that requires JAVA 1.4. If you have JAVA in your classpath, you can use the following command:

java -jar pathToJar/yuicompressor-2.2.jar ––charset UTF-8 -o pathToOutput/filename pathToInput

If you use ant to build, then you might find the following helpful:

<java jar=”pathToJar/yuicompressor-2.2.jar” fork=”true” failonerror=”true” output=”pathToOutput/filename”> <arg value=”––charset” /> <arg value=”UTF-8″ /> <arg value=”pathToInput/filename” /> </java>

One important thing to note is that if you don’t include the “––charset <charset>” option, the compressor with print

“\n[INFO] Using charset UTF-8″

at the beginning of each file, which will break your JavaScript.

Additional Documentation

posted by Matt Snider at 5:46 pm  

Friday, September 21, 2007

More on Really Simple History

So contrary to my last post, it does work in Internet Explorer. I had accidentally overwritten their blank.html file with the one used by YUI. This file is required for the IE IFRAME and contains a callback to “window.parent” (the browser window that you are using dhtmlHistory in). If the following is missing, then IE won’t work:

<script language=”JavaScript”> function pageLoaded() { window.parent.dhtmlHistory.iframeLoaded(window.location); } </script> <body onload=”pageLoaded()”></body>

I never did manage to get it working in Safari 2 or 3, so if anyone knows of a back history method that works in Safari, please leave a comment.

I have two working demos now, one uses the files provided and the other uses my cleaned up YUI version.

Standard Version

My YUI Version

What is the difference?

My version uses my favorite pattern (Module) instead of the Prototype Pattern, which reduces confusion and truly makes functions and variables private. I use compliant DOM method, “document.createElement()”, instead of “document.write”. This also eliminates the need to use “document.getElementById()”. Also, as long as you wait for the DOM to be ready, leveraging “YAHOO.util.Event.onDOMReady()”, you do not need the “window.dhtmlHistory.create()”, as everything can be done in your initialization method. Lastly, because we are leveraging YUI, I demonstrated the unobtrusive way to do this demo. You could also remove the JSON Object and replace it with something simpler that meets your needs and that will save you another 5k.

posted by Matt Snider at 7:08 pm  

Wednesday, September 19, 2007

Really Simple History

For my Mint project, I have been asked to capture the back button and simulate browser history for AJAX GET requests. We do a lot of AJAX magic on the site that looks to the average web user as if the page has reloaded, such as requests to: sort, search, filter, and paginate bank transactions. The product/marketing teams expect instant, desktop-like response (hence the AJAX), but they expect the browser to behave as a traditional browser does. And so the nightmare begins…

After spending the last week examining possible techniques for capturing the back, I have decided to use an approach that implements an IFRAME to queue browser history, and the “window.location.hash” value to store and allow dynamic history positions. YUI History uses this approach and I believe GWT does as well. However, I do not know GWT very well and it took me several hours to get the YUI History manager to work (and that was before doing anything with AJAX). In the end I decided to choose this light-weight package, Really Simple History, which was so easy that I had their demo working in under 30 minutes.

I have now spent several hours working with this and package and here are some pros:

  • super easy to setup
  • lightweight and standalone
  • fairly easy to understand
  • works well in firefox, IE, and opera

and cons:

  • when calling updateUI, if historyData is not null, I always get a too much recursion error
  • doesn’t support safari

That said, after refactoring the library to use YUI and the module pattern, I was able to shrink the size even further and have it mostly working in IE 6 & 7. I will continue working on it this week and hopefully will be able to write a working demo by Friday, supporting all listed browsers and Safari.

posted by Matt Snider at 6:23 pm  

Tuesday, September 18, 2007

Mint Launches

I have been working on Mint for the past year and am please to announce that we are out of BETA. We went live right after our presentation at the TechCrunch40 Conference this morning. If you are curious about your finances and want an effortless tool to help you manage, then Mint is for you:

Mint Homepage Screenshot

posted by Matt Snider at 12:07 pm  

Friday, September 14, 2007

Two Helpful IE Hacks

For a change of pace, below is a short article about CSS.

* (star) or Holly Hack

In most browsers the CSS root tag is ‘html’, so you might write:

html body { font-size: 12px; }

In, IE (version 6 and lower) Holly (Bergevin, i think), found that the DOM actually starts with ‘*’, so you might write:

* html body { font-size: 12px; }

Because only IE 6 and lower understands the ‘*’, all other browsers (including IE 7) ignore style declarations beginning with star. Because of this, many designers use this hack to apply styles needed only for IE6. Most commonly this is as a result of IE Box Model issue, however, if you build your DOM carefully and don’t apply heights or widths to elements with margins or paddings then you won’t have Box Model issues.

PNG Transparency

Lately, I have been using the holly hack, because IE 6 does not support PNG transparency. If you find yourself forced to use transparent PNGs, then you can use the holly hack to target the element and apply this Microsoft only filter:

* html a.png { background: #FFF; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’relative/path/to/my/png’, sizingMethod=’scale’); }

The filter is a Microsoft only transformation that applies the alpha or index transparency filter for the image. I found with strict doctypes that the filter only works if you explicitly declare a background color, otherwise if you inherit a color, it seems to ignore the filter.

posted by Matt Snider at 6:31 pm  

Friday, September 14, 2007

CustomEvent Bubbling and Capture Phase

Caridy Mayea, a well-known contributor for YUI, blogs about his technique to simulate the JavaScript Event Object native Bubbling and Capture Phases with CustomEvents. This is a good read whether you intend to use this technique, or you simply would like to understand the event phases better. Check it out:

Bubbling Library

posted by Matt Snider at 6:06 pm  

Friday, September 14, 2007

jQuery 1.2 Released

If you didn’t already know, jQuery is a lightweight JavaScript Framework that introduced powerful DOM querying and Function chaining. Check out their documentation for more information.

The team has added a lot in this version, rounding out the Framework’s rough edges. It is important to note that this version is not backwards compatible with previous versions and you will need to use the supplied plugin for jQuery 1.1.4 backwards compatibility.

jQuery 1.2

posted by Matt Snider at 5:59 pm  
Next Page »

Powered by WordPress