No Mod Required

Archive for the 'javascript' Category

Books 2008 #1 Pro JavaScript Techniques

Pro JavaScript Techniques (Pro) Reading this book I finally understand why I don’t really immediately grasp JQuery code. Resig’s doesn’t use verbs for his function names. Instead of something like getElementsByClass(), he uses something like class(). I like verbs in my function names.

That aside, this is an excellent book for the serious JavaScript programmer. Resig does a great job of covering the breadth of modern JavaScript techniques and if you’ve got a reasonably solid JS foundation you can’t help but come away from this book with patterns, techniques and approaches that you can apply to your day-to-day code.

Playing Around With ECMAScript for XML (e4x)

As I mentioned I was reading John Resig’s Pro JavaScript Techniques recently (I actually finished it today.) The last chapter deals with the future of the language, and goes into a few different JS related technologies on the horizon- the <canvas> element, Comet, etc. One technology featured I’d never actually played around with was ECMAScript for XML (E4X.) Reading the sample code, I realized it could potentially be really useful, so I decided to take it for a little spin this afternoon, just to get a feel for what it might be like to work with. I came up with the following…

Here’s some sample code:



function e4xDemo() {
      //create a new div
      var newDiv = <div/>;
      //append an H1 with some text 
      newDiv.h1 = "This is an e4x generated header";
      //give the div an ID
      newDiv.@id= "e4x";
      //append an H2 with some text
      newDiv.h2 = "let’s create a more complicated structure"
      //append a whole slew of divs and a paragraph
      //this feels like it could be very powerful
      newDiv.div.div.div.div.p = "isn’t this kind of cool?";
      //add another paragraph
      newDiv.p = "let’s add in an image";
      //if E4X was widely supported
      //I’d use this pattern all the time
      newDiv.p.img.@src="http://media.drunkenfist.com/304/wp-content/uploads/2008/01/graffiti-letter-i.thumbnail.jpg";
      //E4X creates a variable of type XML
      //Which is basically just a string full XML
      //so we use innerHTML to jam it into the doc
      $("contents").innerHTML=newDiv;
      //Then we spit out the full text of the variable into a PRE
      $("view-source").appendChild(document.createTextNode(newDiv));
      //use the .. operator that searches all child nodes of a certain type
      $("dot-dot-p").appendChild(document.createTextNode(newDiv..p));
      return false;
  };


And here it is in action (Firefox only):

First impression? It wouldn’t completely replace strings+innerHTML or the proper DOM methods like createElement or appendChild, but E4X would come in handy in a lot of situations and if it were more widely supported it would immediately get some use. For example, I’d definitely use the var newImg = img.@src = "path/to/image" pattern all the time when creating images on the fly (it’s just so direct) and I’m betting I’d use <div/> and div.@id in place of some of the longer, tougher- to- read strings I drop into HTML docs with innerHTML.

I’m going to continue to experiment with it. I’m going to try to rewrite some of my existing code using E4X, so we’ll see what shakes out with the tinkering.

JavaScript Dispatches From My Kilobyte Addled Brain.

I’m reading John Resig’s excellent Pro JavaScript Techniques. A great book for any JavaScript programmers in the audience.

Anyway, last night I was reading the chapter on image galleries. In it, Resig, comparing Lightbox to Thickbox, writes:

“Due to the amount of extra features that ThickBox includes, along with the reduced code base, it is certainly a desirable alternative to Lightbox”

The part about the reduced code base struck me as a bit odd as Thickbox requires JQuery to function. At the time of reading I thought JQuery was about 30k packed (it turns out it’s 26.5K packed,) so to my mind, Lightbox, which is a standalone script, being bigger than that seemed improbable. And that estimate didn’t even factor in the Thickbox code itself.

Stranger things have happened of course, so I spent a few minutes today looking into all the pieces to flesh out the story and now I think I see what Resig was referring to- if you’re already using JQuery, the Thickbox script file (11.3K unpacked/ 5.83K packed :) ) is smaller than the Lightbox script file (12.3K unpacked.)

It’s especially nice that Thickbox pushes a packed version at the user, by the way.

That said, my original “huh” was justified as, if one is starting from scratch or adding a feature to an existing site that doesn’t already use JQuery, then the total code cost for inserting Lightbox is considerably smaller than Thickbox (JQuery IS getting served to the browser after all.)

Of course, if you take a look at Lighbox 2, then Resig is even more right as the total cost of code on that one, written on top of Scriptaculous and Prototype, is 103K.

For what it’s worth, that’s nearly twice the weight of my whole home page.

What does all this mean? Nothing? Everything? Who cares? Something like that :)

Sharing is Caring- Using JavaScript to Enable Image Sharing

People hijack my images all over the web. Yes. It’s true. While I’m not 100% happy about it, I’m also not 100% upset about it since I’m glad that people like my images enough to swipe them. So I tolerate it.

One thing that would make it all a lot more palatable is if people who were taking my images would link back to my site. The link would serve as credit, would drive traffic, and would increase my page rank. What’s not to love?

To that end, I wrote up a little script last week that I attached to all my gallery images to maybe, just maybe, help people to do just that.

Want to try it out? Click through to view the glory of my “trouble” graffiti canvas. When you’re there, right click on the image- as if you were going to “Copy Image Location.”

Wasn’t that cool?

For the lazybones in the audience who haven’t actually clicked through, right clicking on the image triggers a little JavaScript function that throws this at the user

sharing-is-caring.jpg

As you can see it’s a fairly friendly option to grab some easy-to- paste code in order to share the image. How nice am I?

If anyone actually uses it instead of just stealing the image then the whole process would be a resounding success. Traffic + page rank = good times.

Want to know how it’s done? The code follows. For what it’s worth, I’ve translated this into plain old JavaScript. There are some shortcuts that my actual code uses that I’ve turned back into native objects and methods so that it should be more readily grasped by folks no matter what style or library they might use in their day-to-day coding:

Anyway, on page load (either window.onload or whatever enhanced version you use- I use this ) I run this block:

if (document.body.id=="grafpg" || document.body.id=="comicspg" || document.body.id=="artpg" ) {
document.body.innerHTML+="<div id=’msg’><div id=’msg-body’><h3>Want to share this image?</h3><label for=’grablink’>Here’s the code to paste into your blog, forum post, myspace, etc :</label> <textarea name=’textarea’ id=’grablink’></textarea><p id=’download’></p><p>All images &copy; Rob Larsen</p></div><div id=’clear-msg’></div></div><div id=’cloak’></div>";
createShareLinks();
}

In my specific case I know that pages with ids of grafpg, comicspg and artpg are the page types that will have gallery images I want to manipulate. If any of those three page IDs show up, I use innerHTML to append the basic structure of the overlay to the page. As a note, because I have this structure already in place, this script is completely unobtrusive. I didn’t need to change the HTML at all to implement this functionality. Such is the benefit of thinking a little bit about the semantic meaning of ID and CLASS attributes. Since went so far as to separate the three “types” of art page, even though they display exactly the same, I could conceivably present three separate versions of the interface depending on the site section, still without touching the underlying HTML. Structure is cool.

I should mention I love this sledgehammer approach to appending content to a page. I admit it wholeheartedly. It’s just so damned direct I can’t help but smile. Don’t get me wrong, I love createElement, appendChild, etc. and use them all the time. It’s just, being an HTML guy at heart I love to be able to mock up a display like this and then just drop it into a page with very little fuss. HTML source to JavaScript flashiness in no time flat :)

Anyway, after appending the overlay divs, I initiate the guts of the behavior with the createShareLinks() function. The source of which follows:

function createShareLinks(){
// there can be more than one img on a gallery page. Get the full nodeList of images
   var theImg = document.getElementById("artimg").getElementsByTagName("img");
// and loop through
   for ( var i=0;i<theImg.length;i++ ){
// attach an event to the contextmenu event
// did you know there was such a thing?
      theImg[i].oncontextmenu = function() {
// do come calculations to create the proper
// height and width for the cloak and msg divs;
         document.getElementById("cloak").style.width = document.getElementById("msg").style.width = this.offsetWidth  + 2 + "px";
         document.getElementById("cloak").style.height = document.getElementById("msg").style.height = this.offsetHeight + 2 + "px";
// there’s some padding we need to take into account
         document.getElementById("msg-body").style.height = this.offsetHeight - 32  + "px";
// get the x and y of the image and set the
// top and left of the divs accordingly
         document.getElementById("cloak").style.left = document.getElementById("msg").style.left = (findX(this) -1) +"px";
         document.getElementById("cloak").style.top =  document.getElementById("msg").style.top =  (findY(this) - 1) +"px";
// build the link text.
         document.getElementById("grablink").value="<a href=’http://www.drunkenfist.com/’><img src=’"+this.src+"’  alt=’image copyright rob larsen’ /></a>";
// I just like this
         document.getElementById("grablink").onfocus = function() {
            this.select();
         };
         document.getElementById("download").innerHTML="<a href=’"+this.src+"’>Download this file</a>";
         document.getElementById("clear-msg").onclick= clearShareLinks;
// show the divs
         document.getElementById("cloak").style.display = document.getElementById("msg").style.display = "block";
         return false;
      }
   }
};
//a simple function to hide the overlay;
function clearShareLinks() {
   document.getElementById("cloak").style.display = document.getElementById("msg").style.display = "none";
}

First I create a nodeList of all images contained in div id=”artimg.” Once I have that nodeList, which will contain either one or two nodes, I loop through and attach an oncontextmenu event handler to the image. Did you know there was an oncontextmenu event handler before reading this article? If not, now you do :) In the function that fires when a user right clicks (or control clicks) on an image I do some basic dHTML goodness. First I set the height and width of the two divs to equal the height and width of the target image and then I use the target image to calculate the left and top of the divs so that they sit right on top of the image. Once that’s all set I do some string manipulations to build out the link, some random other housekeeping and then I flip the switch and show the divs to the world in all of their glory.

By the way- are you thinking… “why two divs?”

Well, the one div, the one you’d expect to be the parent, I want to be semi-opaque in order to cloak the image. Thing is, one of the properties of CSS opacity is that all child elements inherit the parent’s opacity. Meaning I couldn’t have 100% opaque text inside a DIV with 80% opacity. Which would suck since it would be tougher to read. Instead, I fake it with two DIVs styled to act as one. Fun times.

Want to see the CSS?

Here it is:

#msg, #cloak {
  position:absolute;
  width:0;
  height:0;
  left:0;
  top:0;
  display:none;
}
#cloak {
  opacity: .50;
/* IE, if you need this to validate, move into a separate IE sheet */
/* and hide from other browsers/ the validator with conditional comments */
  filter:Alpha(opacity=50);
  z-index:9998;
  background-color: #0099FF;
}
#msg {
  z-index:9999;
}
#msg-body {
  width:75%;
  margin:auto;
  padding-top:35px;
}
#msg-body h3 {
  background: #ddd;
  padding:5px;
  width:100%;
  color:#000;
  border:1px solid #000;
  border-bottom:3px solid #000;
  border-right:3px solid #000;
}
#msg-body p {
  width:100%;
  background: #ddd;
  padding:5px;
  border:1px solid #000;
  border-bottom:3px solid #000;
  border-right:3px solid #000;
}
#msg-body label {
  font-size:.82em;
  font-weight:bold
  display:block;
  padding:5px;
  background: #ddd;
  width:100%;
  margin-bottom:10px;
  border:1px solid #000;
  border-bottom:3px solid #000;
  border-right:3px solid #000;
}
#grablink {
  width:100%;
  height:100px;
  background:#efefef;
  border:1px solid #000;
  border-bottom:3px solid #000;
  border-right:3px solid #000;
  overflow:hidden;
  font-size:10pt;
  padding:4px;
}
#clear-msg {
  position:absolute;
  right:5px;
  top:5px;
  width:30px;
  height:30px;
/* sprites are my friend */
  background: url(http://media.drunkenfist.com/img/sprite.1.png) -597px -185px no-repeat;
/* make it look clickable */
  cursor:pointer;
  cursor:hand
}

And that’s that. Will it get used? I hope so. If not, it’s the thought that counts, right?

I just realized- JavaScript is my Perl

Twice this morning I did massive, repetitive, string manipulations with JavaScript.

One took a list of files, turned it into an array and then looped through creating .htaccess entries.

The other took an HTML table output by Excel and turned it into a Definition List. I then used FireBug to copy the innerHTML of the body and pasted it into a new document, ready to be manipulated in the application I’m building (with JavaScript of course :) ) If you’re curious, here’s the code for that one:

<script type="text/javascript">
window.onload = function() {
    var trs = document.getElementsByTagName("TR");
    var newString ="<dl>";

    for (i=0;i<trs.length;i++){
        var tds=trs[i].getElementsByTagName("TD");
        newString +="<dt id=’"+tds[1].innerHTML+"’>"+tds[4].innerHTML+"</dt>";
        newString +="<dd>"+tds[5].innerHTML+"</dd>";
    }
    newString +="</dl>"
    document.body.innerHTML=newString;
    }
</script>

Anyway, I’ve done this sort of thing before and I realized that I’m using JavaScript for the sort of administrative scripting that other people would use Perl or Python for.

No, there’s nothing more to this post than that.

:)

I just wanted to point it out since it struck me as interesting.

Does anyone else out there use JS for this sort of thing?

Or am I a complete weirdo?

Now Serving: Freshly Compressed Javascript

I finally got around to compressing this site’s JavaScript file last night. I used /packer/ because I know that it supports conditional compilation. I’m a fan of conditional compilation.

It was funny because there were a couple of lines missing semi-colons that I must have looked at a thousand times before last night and just never noticed that they were nekkid like that. JSLint helped me out a lot with making sure the file was ready for packing.

Anyway, between gzipping and compressing it my JS file screams out to the browser at a tidy 2.67 KB (down from an unadulterated 9.41 KB.) There are probably functions in some libraries larger than that…

Go small or go home!

JSON Feeds For Fun and Profit Part 3- wherein Eval() kind of bums me out

(and several months later I finish my little JSON series…)

So far my exploration of JSON has been a fun-filled walk in the park. Moonbeams and rainbows. All that.

This last post on the subject is slightly less cool as I get into one of the least attractive components of the whole JSON thing- the use of eval() to transform a text response into a proper JavaScript object. The use of eval() is one of the reasons I originally was a little shy about using JSON. Why? eval() is slow and I try to stay away from slow if at all possible. That and the idea of eval()-ing code from some third party makes me wary.

Obviously, if you’re using a callback, or are just using a built in object reference which inserts itself into memory as soon as the script is attached a script to a page, eval() won’t come up, but sometimes there’s no other option but to ingest the JSON feed as plain text and eval() it into Object-hood. The feed I was helping out a co-worker with last week (AKA back in August when I originally wrote this) which spurred on this very series of posts was one such feed. It looked something like this example cribbed from JSON.org:

{
    "glossary": {
        "title": "example glossary",
		"GlossDiv": {
            "title": "S",
			"GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
					"SortAs": "SGML",
					"GlossTerm": "Standard Generalized Markup Language",
					"Acronym": "SGML",
					"Abbrev": "ISO 8879:1986",
					"GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
						"GlossSeeAlso": ["GML", "XML"]
                    },
					“GlossSee”: “markup”
                }
            }
        }
    }
}

As you can see, if you attach that script to the document using a script tag, there’s absolutely no way to get anything out of it. No amount of poking at it will communicate the contents of that file to the rest of the scripts on the page. There’s no reference in memory and there’s no way to create one. It has to be ingested using an XMLHttpRequest and eval() has to bring it into life. Since it uses XHR and not a dynamic script tag, that means a local pass-though script on the server side is needed to get around cross site scripting constraints. In other words, we’re looking at a big pile of “why bother?” For my money, if you have to go through these steps, then plain old XML makes more sense.

Anyway, if you have to use JSON and the only option is a response structured like the above, then the following is one way to handle it.

First, an example “tag cloud” hacked together with a raw JSON tag feed from del.icio.us:

Now some code:

<script type="text/javascript">
function ajaj(json_doc,callback) {
  //ajaJ? get it? so clever.
  //create a cross browser XMLHttpRequest object
  //let’s do this
  	http= new function() {
  	var xmlhttp;
  	try {
  	//start with the standard
 	 xmlhttp = new XMLHttpRequest();
 	}
 	catch(e) 
  	{
 	 //do the IE thing if the above fails
	  //IE deserves some props since they actually created 
 	 //the whole XMLHttp thing
  	xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  } 
  return xmlhttp;
  };
  //is it okay to try this?
  if((http.readyState==0)||(http.readyState==4))
  {
  //I do this in a try/catch since  there’s 
  //always a chance of some 
  //sort of data error and I want the 
  //possibility of using a fallback function
  //if there is some sort of internet hiccup. 
  //I also hate showing errors to the user
  //In this case I could just drop it since
  //I’m not doing anything special here, but 
  //I’m not about to reinvent the wheel
  //since this is more about JSON 
  //than the way I use XMLHttpRequest 
  try 
  {
  //open the connection
  http.open("GET", json_doc, true);
  //set up a function to handle the response
  http.onreadystatechange = function handle_http_response() 
  {
  //I take no chances.
  //you can have have readyState of 4, a status 
  //of 200 and still run into trouble
  //I want to know all my ducks are in a row :) 
//I’m all belt and suspenders 
  if ((http.readyState == 4)&&(http.status==200)&&(http.responseText!=null)) 
  { 
//First I create an empty object, the same structure as the regular Delicious JSON feed
//I like the structure of their feeds so I’m replicating them here.
  Delicious = {}
  //Use eval to bring the response into the Object
//Again, I’m using Delicious’ own Delicious.tags structure
  Delicious.tags=eval(’('+http.responseText+’)');
  //we’ve got this handy object now that we’ve done our eval
  //we pass it as an argument to the callback function
  callback(Delicious);
  }
  }
  }
  catch(e) 
  {
  //we could do some stuff here to handle errors
  }
  //let’s put an end to this transaction
  http.send(null);
  }
  }
  //this is the callback function
  function delicious_me(Delicious) {
  //this is an object functioning as 
  //an associative array
  //not a proper indexed array typical of most JavaScript
  //so we use a for… in loop
  //which loops through all the members of the array by named reference
  for (var i in Delicious.tags) {
  //inside the loop i will refer to the property name
  //tags[i] will return the value
  //BTW, the tag cloud is a total hack. 
  //I should do some better math here, 
  //but like the XHR stuff above 
   //this isn’t really about a tag cloud…
  document.getElementById("delicious").innerHTML+="<a href=’http://del.icio.us/rob_react/"+i+"’ style=’font-size:"+Delicious.tags[i]/2+"px;line-height:"+Delicious.tags[i]/2+"px;’>"+i+"</a>\n";
  } 
  }

The interesting bit, at least in the scope of this article, is this where we use the eval method to pull the responseText into the Delicious and pass it to the callback function.

Delicious.tags=eval('('+http.responseText+')');
callback(Delicious);

Nothing groundbreaking there and, honestly, not much for me to get excited about. I just don’t like the use of eval and would go to great lengths to avoid using it. That said, if you’re in a situation where a raw JSON feed is all you’ve got to work with, this is a way out of the jam.

For my next, and final entry in this I’ll use this handy JSON parser for the safe alternative to eval(). That should make me a little happier than this example.

Belt and Suspenders- Flash Embed With SWFObject and Conditional Comments

If you’re using Flash and you want the best possible coverage (meaning it works with users who don’t have JS turned on) while still using something like SWFObject where possible to get around the “click here to activate and use this control” ActiveX message in Internet Explorer, then take a look at the ridiculous pattern below.

Warning- not for the squeamish…

Here’s the HTML:

<!--[if IE]>
   <noscript> 
   <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="1004" height="281">
      <param name="movie" value="_assets/flash/homepage.swf" />
      <param name="quality" value="high" />
      <embed src="_assets/flash/homepage.swf" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="1004" height="281"></embed>
</object>
</noscript>

<![endif]–>
<!–[if !IE]> <–>
   <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="1004" height="281">
      <param name="movie" value="_assets/flash/homepage.swf" />
      <param name="quality" value="high" />
      <embed src="_assets/flash/homepage.swf" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="1004" height="281"></embed>
   </object>
<!–> <![endif]–>

Here’s the SWFObject script served to Internet Explorer and ONLY Internet Explorer

<!--[if IE]>
<script src="_assets/js/swfobject.js" type="text/javascript"></script>
<![endif]–>

And here’s the SWFObject call:

        //use conditional compilation to hide this call from non-IE browsers
	/*@cc_on @*/
        /*@if (@_win32)
	if ($(”home”)){
		var so = new SWFObject(”_assets/flash/homepage.swf”, “mymovie”, “1004″, “281″, “8″, “#336699″);
	   	so.addParam(”wmode”, “transparent”);
	   	so.write(”messaging”);
	}
	/*@end @*/

Before I go further, let me just say I’m counting the days until I can just dump a SWF into the page and be done with it. I hate all of these script based machinations to get a SWF out to the browser. This is code overhead that really bugs me…

Anyway, here’s the HTML logic.

  • We use Microsoft’s conditional comments to show/hide content
  • In the “This is IE” block we use a noscript tag to present a traditional embed to IE users who might have JS turned off.
  • Every other IE user with JS turned on will see the SWF embedded by SWFObject so no “click to activate and use this control” will be visible to the user. Since the majority of people on the web use IE and the majority of them surf with JS turned on, most users will fall into this category.
  • Then, in the “This is not IE” block, we just embed the Flash the old school way. Since the Eolas suit doesn’t come into play with other browsers, embedding the SWF the old way is fine (at least in terms of the “click here…” nonsense.) As an additional benefit there’s no concern over whether or not the user has JavaScript turned on. JavaScript or no, the only issue is whether or not they have the plugin. Whereas with SWFObject there’s a possibility (however slim) that a user could have the Flash plugin installed but be surfing with JavaScript disabled. As I mentioned, this is for the best possible coverage… Also, if they don’t have the plugin they get the “download this plugin” notification. I head reports that that wasn’t happening with SWFObject running* so getting that to work properly is definitely a bonus. It was actually that bug report that got me into this whole mess :)

As for how it works technically, the following

<!--[if IE]>

Is read by IE as a test (if the browser is Internet Explorer.) Every other browser reads it as an open comment. Since it’s an open comment everything up until the close comment (<![endif]–>) will be ignored by non-IE browsers. IE, on the other hand will go ahead and process that markup normally since it recognizes that pattern as a conditional and its test will evaluate to true.

As a note, I don’t like using this stuff all over the place**, but in a situation like this conditional comments are a great option to have.

On the flip side All other browsers read this pattern:

<!–[if !IE]> <–>

As a completed comment, opened and closed on the same line. Therefore everything that follows is rendered normally by Firefox, safari and all the rest. IE, on the other hand, reads it as the beginning of a “If the browser is NOT IE” conditional. Since that resolves to false, everything down to the end of the conditional endif (<!–> <![endif]–>) is ignored by Internet Explorer. That allows us to go back to the future and embed flash in the old school way for everything but IE.

Oh the pain.

Still, if you absolutely need the best possible coverage and want to use SWFObject, this is a way to go. Is it the best? Probably not, since it’s horrifyingly hack-y and won’t validate. But it might be useful for someone out there…

*and I could figure out how to make it happen…
**I mostly use it to attach IE specific style sheets. For those of you keeping track, that looks like this:

<!--[if gte IE 5.5]>
<![if lt IE 7]>
<link rel="STYLESHEET" type="text/css" href="_assets/styles/ie6.css" />
<![endif]>
<![if gte IE 7]>
<link rel="STYLESHEET" type="text/css" href="_assets/styles/ie7.css" />
<![endif]>
<![endif]–>

No wonder they contacted me all the way from Cali…

Yahoo! is training front end developers to fill their staffing needs…

The Harvard Of JavaScript Training (Yahoo! Developer Network blog)

When you think of prestigious law schools, it’s Harvard. Computer Science? Maybe MIT or Carnegie Mellon. When it comes to front end engineering though, Yahoo! Juku may be the best bet. Taught largely by our in-house front end pros, including YUI developers Nate Koechley, Yahoo! Juku Nicholas Zakas, and Thomas Sha, and JSON inventor Doug Crockford, Yahoo! Juku is a comprehensive, 3-6 month program to train professional front end developers. The curriculum includes advanced topics in JavaScript, DOM, HTML, CSS, YUI, performance, and accessibility.

Why train raw recruits to this degree? Well, in the San Francisco Bay Area, including the Silicon Valley, it’s hard-as-heck to find good front end programmers and web designers. Things aren’t as crazy as in 1999, when many companies seemed to grab random people off the street to do front end development, but top talent is still scarce. The first class of 13 Juku graduates will toss their hats into the air on December 14th!

Dear Yahoo! You don’t need to go to all that trouble… just open a Boston office or let me telecommute and I’m all yours! I’ll even give up “Plain Old JavaScript” and hitch my wagon to YUI full time! That’s dedication.

Books 2007 #14 PPK on JavaScript

ppk on JavaScript, 1/e (VOICES) Another excellent introductory book. I got this mostly as a way of thanking Pete Paul Koch for all of his invaluable work over the years at quirksmode.org, but reading it was still a worthy way to spend my time. Not surprisingly (since he knows his stuff backwards and forwards) it’s an excellent book, well written, easy to follow and very thorough. I’m going to recommend it going forward to anyone looking for an introduction to JavaScript programming.