No Mod Required

Archive for the 'ajax' Category

Some Internet Explorer Innovations You Probably Forgot About While Waiting for IE6 To Die

Lost in the past few years of IE6 based stagnation (and ensuing developer angst) is the fact that the Internet Explorer team have come up with some pretty cool enhancements to the way we build web sites over the past ten plus years.

So, while we’re cheering on Firefox’s growing market share, hesitantly eying IE8 and waiting for the ugly stepchild of the browser landscape, IE6, to finally die a painful (and hopefully immediate) death, I thought I’d lay out some of the innovations introduced by Internet Explorer to remind us of relatively positive days gone by*.

As a fun exercise, while you’re reading this, compare these innovations to the black hole left in the web development world by the long and terrible reign of IE6. It’s an interesting juxtaposition of help vs. harm. Here’s hoping future versions of the browser continue to trend closer to the “help” line as IE7 has and IE8 appears to be doing**

XMLHttpRequest

For those that don’t know, XMLHttpRequest (XHR) is an API used by JavaScript to transfer XML (and other text formats like JSON and plain text) data between a browser and the web server.

This one is obviously pretty big. While “Ajax” the phrase coined by Jesse James Garret of Adaptive Path, didn’t spring directly from Redmond, a large part of it, and therefore much of the recent innovation in the way web interfaces are programmed, does spring from the creation of the XMLHttpRequest (XHR) object. Originally an ActiveX object, XHR is so far entrenched into the way web works right now it’s not even funny.

Personally, without Ajax making JavaScript the hot language it is today, I wouldn’t be half as marketable as I currently am.

Introduced in Internet Explorer 5.0

innerHTML

This JavaScript property is a read/write interface to the HTML markup and content within a given element.

All day, every day I use the innerHTML property. Faster than the DOM methods for object creation and insertion setting innerHTML is normally my first choice whenever I do DOM manipulations.

Introduced in Internet Explorer 4.01

iFrame

Like a frame, an iframe (”inline frame”) is an HTML element that allows you to embed a HTML document inside another HTML document. The iframe is the earliest innovation this list, appearing all the way back in 1996.

Humorously (or tragically depending on where your allegiance lies- Mountain View or Redmond,) a good portion of the GOOG empire is built on the iframe as the search giant uses an iframe to deliver its advertising on non-Google properties (you can see one in action on this very page.)

Introduced in Internet Explorer 3

The favicon

A favicon (favorites icon) is an icon associated with a particular website or webpage. The favicon not be the innovation that affects me the most on a day to day basis, but judging by the chatter generated by Google’s new favicon, I think a lot of people notice that little browser accessory.

Introduced in Internet Explorer 4

overflow-x, oveflow-y

Maybe not the biggest impact, being able to set the overflow property in one dimension is an immensely handy thing to be able to do and I’m happy to have it in my list of tricks.

*This is 100% focused on only technology. Anti-competitive practices and killing Netscape are definitely NOT positive.

**it should be added that while I’m pleased to develop for IE7 in comparision to IE6, it still falls short of what I’d like to see in terms of standards support. Hopefully IE8 will knock it out of the park, but until that time, I’d much rather everyone just go with Firefox, Safari or Opera :)

Say Hello to JavaScript’s Native getElementsByClassName

With the recent release of Firefox 3, we’ve now got a full fledged, mainstream browser that supports the long-awaited, often replicated, getElementsByClassName method. This is good news as we’ll all be just that much speedier as we ditch the various helper functions and go right into the browser for that functionality.

The thing is, the transition, when we’ll finally be able to make it, isn’t a one to one swap. In fact, depending on what you’re using it for you could run into problems transitioning from a helper function to the native method.

Why? Well, the native getElementsByClassName returns a NodeList and the functions an Array. This is a fundamental point as a NodeList, while it has a length and can be accessed by a numerical [index], isn’t an Array. One major difference, and the one that might cause serious problems if you’re not careful, is that it’s live. It doesn’t merely grab the returned value at the time of invocation, it updates its members as the document changes over time.

Here’s a simple example where I run the two versions side by side. Click start and both functions will count the number of “sample” classed elements in the document. A couple of seconds later I simply copy the innerHTML of the container DIV, doubling the number of “sample” elements on the page. As you then see a couple of seconds after that, the native code notes the adjustment to the document, the helper function does not. The counts are different.

Check it out (assuming you have a browser that supports getElementsByClassName):

Why is this important? Well, I don’t know about you, but in doing dynamic effects I often attach classes to elements so that (a) I can add effect-specific styles to them (duh) and (b) I can remember what state they’re in when I next run the function. A lot of times when a function is run I’ll take a snapshot of that collection and run some code like this on it:

var currSelected = getElementsByClass("sample");
		for (var i=0; i<currSelected.length;i++) {
			removeClass(currSelected[i],"sample");
		}

Which ensures that I’m starting with a clean slate by removing class “sample” from every element.

This is where it gets tricky. If I did that with the native getElementsByClassName I would get a weirdo result that looks like this. Click start and run the above code with getElementsByClassName in place of the helper:

For those of you without a compatible browser here’s a screen shot of the result:

With the helper function there would be no blue borders. Since getElementsByClassName is a live connection to the document, both the length and the elements at each index CHANGE as you remove elements from the document.

The reverse would be even worse. Adding classes to elements based on getElementsByClassName would create an infinite loop, since i will never be less than collection.length. Every time you add a new class the length increases by one and the loop never ends.

What does this all mean in practice? I’m thinking I’m going to keep my old reliable getElementsByClass function (or a variation that leverages the native method but returns an array “snapshot”) and selectively use the native method where applicable.

[edited] as was suggested in the comments, I wrote a new getElementsByClass to take advantage of the native code.

Dear Internet, Is There Any Reason I Wouldn’t Want to Do This?

Got firebug? Load this test page: Simple Style Graffiti Canvas and watch as I load the “previous” and “next” pages with XHR, parse out the image tags in each, adding them to the users cache.

Is there any reason I wouldn’t want to do that?

The performance benefit in the browser is a huge reason TO do it.

But what about the flip side?

I’m already thinking about the extra requests that might not be actually used by visitors who don’t follow the back and next path? Those could add up maybe. If I implemented this my site would handle an extra 3 php requests per initial page load and then two cached requests and one new request each additional page. But, that doesn’t seem like a big deal to me.

Again, am I missing something?

Anything else?

JSON Feeds For Fun and Profit Part 2 - Callbacks with Twitter

In my first exploration of the JSON data interchange format, I used it in its most basic way possible. I attached a script (from delicious) to a page and simply used the built-in object created by their implementation to generate an unordered list of my recent del.icio.us posts. While it showed how easy it is to use the O, a handy, structured, Javascript Object, provided by JSON, it didn’t really illustrate how to manipulate the page with new data after page load. That is, after all, a very now thing to do, so it’s kind of important. This article will examine how to dynamically load a JSON feed and how to get data out into a usable form using a callback.

While one can load JSON using XMLHttpRequests, the real benefit of JSON is to be able to load data from a third party without worrying about the browser security model and without having to rely on a local pass through file. So, we’re going to load the data without XHR in this example. Instead we’re going to load it using dynamic script tags.

Here’s the function I’m using in my example:

function twitter_me() {
   var twitter_JSON = document.createElement("script");
   twitter_JSON.type="text/javascript"
   twitter_JSON.src="http://twitter.com/statuses/user_timeline/rob_react.json?callback=twitter_callback&count=10"
   document.getElementsByTagName("head")[0].appendChild(twitter_JSON);
}

First I create a new script element in the document, then I set the type and source. The source is the interesting part. As you can see, after the URL for the JSON document representing my twitter updates, I append a query string. The first argument for that query string (callback=twitter_callback) is where the magic happens. There I’m defining the function that will be called when the script is attached to the document. To see what happens compare the first few characters of the JSON script called with and without the callback.

Here it is, as referenced in the above code

twitter_callback([{"source":"web","text":"426 queries in 107.66 milliseconds. drupal is teh awesome",

and called without the callback (but with the count, so the data structure returned is the same)

[{"source":"web","text":"426 queries in 107.66 milliseconds. drupal is teh awesome",

Notice the function referenced in the first example. Right there, as soon as the JSON document is loaded, JavaScript executing the callback function with the JSON object as an argument. I'm a JavaScript geek and all, so I'm biased... but that's just plain cool.

So what happens next, you ask? Well, since I defined a function called twitter_callback, that function is run and I'm able to do all sorts of cool things with the provided object. Here's the function in all its glory:


function twitter_callback(twit) {

 //this is the div I'm writing the content to
 var t_div = document.getElementById("twitter");

//these are some other variables, mostly
 //placeholders so that the code is a little clearer
 var who,what,when,icon, bgcolor

//start the ul
 t_div.innerHTML = "<ul>"

   //loop through the twit object
   for (i=0;i<twit.length;i++) {

   //Look at me use the JavaScript modulus operator to do even/odd rows.
   if(i % 2) {
      bgcolor="#efefef"
   } else {
      bgcolor="#ddd"
   }

   //Right here, I've broken out the separate bits of the string into placeholder variables
   //so you can more easily see the dot notation and array indices in place
   //once you figure out the structure it's dead easy to reference data in an Object
   icon=twit[i].user.profile_image_url;
   who=twit[i].user.name;
   what=twit[i].text;
   when=twit[i].created_at.substr(0,19);

   //and here I mash it all up into a fancy li
   t_div.innerHTML +="<li style=’background:"+bgcolor+" url("+icon+") no-repeat’><strong>"+who+"</strong>: "+what+" ("+when+" GMT) </li>"
   }
  //and close the UL
  t_div.innerHTML += "</ul>"
}

Here it is in action (be patient, Twitter can be slow):

Call me crazy, but that’s something like 75% away from being a widget and there are no cross domain concerns to deal with so it could easily be spread far and wide. There’s a lot to like right there :)

That’s it for this time. Feel free to ping me with questions or comments.

Next up, as I mentioned, one can load JSON via XMLHttpRequest, so I’ll be building an example that does just that. There’s a wrinkle tossed in with that technique that will make things, if not tougher, a little less cool (eval(), I’m looking in your direction.) More on that when I put it all together.

JSON Feeds For Fun and Profit, Part One- Del.icio.us makes it easy

Confession time: I’ve never actually worked with a JSON feed.

No, really.

I know what you’re thinking… Yes, you’re right. I’ve built a bunch of Ajax-y components and one full blown application over the past two years.

No, in light of that it doesn’t make any sense that I haven’t used JSON before.

Anyway, I’ve been helping out one of our developers at work with My Big Javascript Brain™ and I’ve had to mess about with JSON a little bit. She’s ostensibly a Java developer, but she’s shown a willingness to help out wherever she can (thereby learning a bunch of other web technologies,) so this week she’s been tasked with creating a JSON fed Google widget. This has been interesting for me, as I’ve had to guess a lot and leap at solutions at every turn to try to help her (since I have no practical experience with the acronym myself.) The good thing is I’ve actually been helpful. Apparently I’ve soaked up enough about JSON through osmosis or something, because when that feeble amount was blended with my regular JS knowledge I was actually able to piece together some of what was going on. Go me.

Anyway, to actually know what I’m doing the next time, I’ve decided to play around with some feeds right here and write up what I discover to help solidify my own knowledge and to help out anyone else who might be wondering about the magical world of JSON feeds.

Did I mention that they were magical? They are. They’re made of pixie dust and rainbows.

Yes, I’ve gone slightly off the rails… ignore that last bit.

To start with, I decided to use the handy feed from one of my favorite web twenty web sites, del.icio.us. Not surprisingly, since del.icio.us kicks all kinds of ass, they make it dead easy to use JSON feeds. All it takes is attaching the script generated at http://del.icio.us/feeds/json/user_name to a document and a Delicious JavaScript object is automatically created- full of all sorts of social bookmarking goodness. Notably a posts array which contains all of the selected user’s posts.

You can read their concise documentation here. They have a nifty sample as well.

Here’s the example I whipped up. This grabs the last 15 bookmarks from my account, takes the link, description and tags and drops them all into a regular old unordered list*.

Here’s the feed itself. As you can see it contains a simple test to see if the Object already exists, an object definition and then an array populated with all of the post data. Pretty straightforward, really.

The following code sample shows how I did it. My comments are inline and in blue.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>JSON part 1</title>

<!--Seriously. This is all it takes to get the object into your document. 
That's really cool, right? I think so-->
<script type="text/javascript" src="http://del.icio.us/feeds/json/rob_react"></script>
<script type="text/javascript">
window.onload = function() {

//this is the built in delicious object. 
//the array posts has all the stuff we're looking for. 
//let's make a quick reference to it
var del = Delicious.posts;
var d_div = document.getElementById("delicious");

// create a placeholder for the link
var the_link=""

//****As a note, I've found writing out innerHTML 
//****to be faster, so I use it. 
//****I actually prefer the elegance of JavaScript's 
//****DOM based node creation and manipulation methods.
//**** but speed roolz, so I play with strings
//**** sometimes this stuff can get really confusing, 
//**** though, so I'll fall back and use
//**** the DOM stuff anyway. 
//**** Anyway, back to the script...

//write the beginning of the <UL>
d_div.innerHTML = "<ul>"

//loop through every element in the Delicious.posts object and do stuff
for (i=0;i<del.length;i++) {

//look at me, I'm doing stuff!
//clear the placeholder for the link
the_link="";

//  add in the opening of the LI and the opening of the anchor
// add a reference to the u (url) of the i member of the del array
// and the d (description) of the same memberr
the_link ="<li><a href='"+del[i].u+"'>"+del[i].d+"</a>";

//are there tags? is there a tags array of the i member?
if (del[i].t) {

//if so lets write them out
the_link +=" <em>tags:</em> "

//loop through all the mambers of the t (tag) array
for (j=0;j<del[i].t.length;j++) {

//and build another link
//here I'm using the simple, but powerful URL scheme
//that delicious uses to nice effect
//by dropping the the tag onto the end of my delicious url
//I'm easily building out links to my tags
//they use a logical, transparent url scheme which makes 
//it crazy easy to navigate both as a user and as a programmer
//go delicious go.
the_link +="[ <a href='http://del.icio.us/rob_react/"+del[i].t[j]+"'>"+del[i].t[j] +"</a> ]" 
}
}

//close out the li
the_link += "</li>"

//pop that link and li into the div
d_div.innerHTML += the_link
}

 //once the loop is done, close the ul
d_div.innerHTML += "</ul>"

//and that's that. like I said, pure magic.
}
</script>
<style type="text/css">

/*I've got style*/
body {
color:#666;

/*by the way, shorthand is your friend!*/
font: .825em/1.8em Verdana, Arial, Helvetica, sans-serif;
}
em {
color:green;
margin-left:10px;
}
</style>
</head>
<body>
<div id="delicious">
</div>
</body>
</html>

And that’s that- a run-through of the simplest possible usage of a JSON feed (at least in terms of extracting the data.) Next time (which should be soon) I’ll look at different methods for getting dynamic data out of JSON. Oh, the fun we’ll have.

(part 2 of this series | part 3 of this series)

*The note is also available- I’ll use that in my next example.

The joy of… JavaScript’s getElementsByTagName()

For what it’s worth the kernel of this article was dictated into my phone on my drive into work this morning. I got the idea, had the framework and figured- why the hell not just talk to myself for a while. It was actually pretty efficient, so I might do more of it and if I get good enough at this sort of extemporaneous dictation I might turn it into a podcast :)

getElementsByTagName is probably my second favorite JavaScript DOM method behind getElementById. By itself getElementsByTagName is very powerful and a combination of the two can create a powerful tool to access DOM elements anonymously. One of the core tenets in my work as a front end developer is to use semantic xHTML markup with no extraneous hooks which I then manipulate with JavaScript. I try for a clear separation between behavior, content and style, so I hate to create classes or IDs just for script. Unless an ID or Class has a real benefit in terms of CSS or has a real, valid descriptive benefit for the document in a semantic sense, I don’t want to use anything other than plain vanilla HTML elements. I hate to add classes or IDs to my documents unless I absolutely have to. It’s a holdover from the days when I was obsessed with bandwidth (even more than I am now) mixed with a desire to have simple, clean code.

To that end I’ve developed techniques to access objects and collections of objects anonymously. One of the most powerful tools in that toolbox is getElementsByTagName. I rely on it all the time.

Now, the most straightforward use of getElementsByTagName, and the one people are probably most familiar with is document.getElementsByTagName. Pass a TD or A as an argument and it will return a nodeList of all the TDs or Anchor tags in an entire document. That’s great if I want to, for some reason, manipulate every DIV, A or TD on a page. The thing is, I very rarely want to manipulate every single item of a certain type on an entire page. Elements are usually used in multiple ways in a document so, what happens in that situation is there’s a huge collection of elements in an array, which have to be looped through and tested for a certain class or other attribute. If I end up doing something like that, I’d rather use a a DOM helper function like getElementsByClass() or something similar. The interesting thing is, you can DOM methods and a little bit of structural markup you can get similar results as getElementsByClass() without having to create any extraneous classes.

That’s because, with the way that JavaScript inheritance works, document, isn’t the only object that can use the getElementsByTagName method. Any object that represents a document or document fragment (node) can provide scope to getElementsByTagName, so it’s easy to limit the the search to a specific object which will represent a specific node in a document. That will then return all child nodes of that Element type of that limited document node. Say, for example, you have a DIV id of “menu”. And you want to manipulate all of the LIs that sit inside of that DIV. So you’d use:

document.getElementById("menu").getElementsByTagName("li")

With that you’d get a smaller nodeList of just the child LI nodes of that “menu’ DIV. That’s a really neat little collection. from there you can easily manipulate each of those to attach behaviors or to mimic the :hover pseudo class in IE6 with JavaScript or whatever else you need to do.

One other great use of getElementsByTagName is using that method on an XML node. Let’s say I’m using the XMLHttpRequest object and it returns some XML data. JavaScript recognizes that XML data as an object with nodes that you can explore and manipulate. One of the easiest ways to get at that data is to use getElementsByTagName. There are other ways to do it- using childNodes and parentNodes to iterate through the XML to test values and properties and the like is an option, but getElementsByTagName can just grab a collection of XML tags. So say there’s an XML document with some arbitrary tags and the script needs to get their value.

In the XHR script the XML response to the request is set to a variable:

xml_document = http.responseXML;

then getElementsByTagName is used

xml_document.getElementsByTagName("yourtag")

which returns a collection of yourtag nodes from the XML document.

One thing I’ll often do, if I know intimately what I’m getting is pass the method a specific index. So if I know I want to get the value of the tag “city” with a name property of “Abington” and I know in advance in the XML document that represents Massachusetts cities and towns, name=”Abington” is the first member of that array I can pass the 0 index to the method and return just that node. Like this:

xml_document.getElementsByTagName("city") [0]

Another thing available here is, if I set xml_document.getElementsByTagName("city") to a variable cities, I can loop through that nodeList and then again use getElementsByTagName on each member of the cities nodeList to get individual child nodes of that XML document. It’s really powerful to couple it and loop through to create these collections of collections which can be manipulated in a lot of ways.

Once common place I use getElementsByTagName is to turn a block into a clickable area. As with everything script related, I really prefer to do it anonymously. I don’t want to know in advance how many blocks there will be, what the link will be, etc. I don’t want to know any of that. I really want someone doing some markup to be able to just edit a link in HTML and then the script will come in on the backside and make the magic happen.

So there’s a collection of these blocks, and a child node in each of these blocks is an anchor. A real anchor pointing to a real URL. Since, for accessibilities sake, I want to use a real link. I don’t want #s or any of that. So what I would is create a collection of LIs:

menu_lis = document.getElementById("menu").getElementsByTagName("li")

and then loop through that nodeList, using the this keyword and getElementsByTagName to reference the href property of the first A child node of each LI, to build out the JavaScript needed to make the whole block clickable

for (i=0;i< menu_lis s.length;i++) {
setHandler(menu_lis [i],'onclick','document.location=this.getElementsByTagName("a")[0].href');
}

And that’s my piece on getElementsByTagName. What’s next? Whatever strikes me on my drive in…

[updated to add]
I forgot to point out one use of getElementsByTagName()- using the widlcard “*” argument. Passing the wild card to the method returns a collection of every HTML element in the document. Which is useful when you want/need to flatten the hierarchy to search the elements on a page. I use it in an example script where I search through every node in an XML document testing attributes.

In the market for some auto-suggest action?

If you are, I just stumbled across this:

AutoSuggest: An AJAX auto-complete text field : CSS . XHTML . Javascript . DOM, Development : Brand Spanking New

I think it looks pretty slick.

Brendan Eich’s presentation from The Ajax Experience

I think I’ll be running through this after lunch, myself.

ScribeMedia » Firefox 2 and Javascript with Brendan Eich

98.75% Billable With Friday to Go.

As I mentioned on Saturday, this has been my first really busy week at work.

It’s honestly nothing compared to some of the days and weeks I saw in 2000 (working full time for one startup-Advisortech and moonlighting for another- Boston’s Weekly Dig), but it’s still somewhat invigorating to go through this sort fo fire drill from time to time.

Unfortunately the work itself is mostly mind-numbing. Cosmetic changes to a site where all the fun work (a little Google maps mash-up and an Ajax log-in) was finished weeks ago.

Speaking of which, the Ajax log-in was the first time I’ve used the hidden iframe mechanism for talking to a server. In a lot of ways I like it as it relies on more of the standard browser mechanisms to get at the data. For example, if the work weren’t based on status codes, I never would have given them a second thought. Compare that to the hoops you have to jump through with the the XMLHttp object (checking both HTTP Status and HTTP Ready States) and it looks like an appealing option. I mean, this is the entire log-in function

function login() {
var remember = “N”;
if ($(”remember”).checked==true){
remember=”Y”
}
var theurl=”/api/auth/signin?username=”+$(’username_field’).value+”&password=”+$(’password_field’).value+”&remember=”+remember
$(”login_controller”).src=theurl
}

All the rest is handled by $(”login_controller”)’s onload event, which fired a function that made some DOM manipulations to display the correct messaging. Really pretty easy, all things considered.

There was one really strange issue- the way IE handles the DOM of an XML document in an iframe. Instead of doing the expected (AKA what Firefox does, namely returning the clean XML DOM of the src document) IE returns the DOM of the color-coded, IE rendered document.

Thanks to the new IE Developer Toolbar, I can now show you exactly what it looks like. I can also see it for myself, since I could only really explore it before with their old DOM inspector and with code. In code it would return ludicrous results for getElementsByTagName(”*”).length. I would get double digits tags for a four or five node document.

This is just the briefest snippet of the rendered DOM of the feed for this blog.

<BODY class="st"><DIV class="e"><SPAN class="b">&nbsp;</SPAN> <SPAN class="m">&lt;?</SPAN><SPAN class="pi">xml version="1.0" encoding="UTF-8" </SPAN><SPAN class="m">?&gt;</SPAN> </DIV><DIV class="k"><SPAN><A class="b" style="VISIBILITY: hidden" onfocus="h()" onclick="return false">-</A> <SPAN class="m">&lt;!–</SPAN></SPAN> <SPAN class="ci" id=""><PRE> generator="wordpress/2.0.7" </PRE></SPAN><SPAN class="b">&nbsp;</SPAN> <SPAN class="m">–&gt;</SPAN><SCRIPT> f(clean);</SCRIPT> </DIV>

Which translates to this in the original XML:

<?xml version=”1.0″ encoding=”UTF-8″ ?>
<!– generator=”wordpress/2.0.7″ –>

I understand that they have to return the referenced document’s DOM. That’s fine. They just need to leave the referenced document alone unless there’s a real reason to muck with it. Making an XML document pretty isn’t a real reason.

It is easy to fix. All you need to do is attach a blank style sheet to the XML doc and everything will work as expected. Still, getting to the point where I understood what was happening and how to fix it was quite an odyssey.

Ajaxian for people who don’t use frameworks?

Is there such a place? I like ajaxian for the pointers to new and interesting Ajax-y sites (it really does help me keep pace with what people are doing), but a lot of times it feels like it’s the Framework News Network. I just don’t care about frameworks and toolkits. I might have a vague interest in what the big boys (Prototype, Yahoo, etc) are up to in terms of releases and features, but that’s the extent of it. So, instead of all that in-depth framework coverage (inclduding framework code examples), I’d like to see a more focus on plain old JavaScript. There are plenty of people writing about Javascript on the Net and there are plenty of people hand-rolling JS solutions. I want an aggregator for that stuff…

Is anyone doing that?