Coding with Jesse

Holiday Time

I hate to do posts like "Sorry I haven't posted in so long" or "I won't be posting for the next while" but... I won't be posting for the next while. I'm leaving tomorrow morning to go back to visit Canada for three weeks, and chances are I'll be pretty busy. But don't worry—I'll be back just in time to do Carnival of the Web #2. See ya!

Published on June 29th, 2006. © Jesse Skinner

Floating Layers versus Popup Windows

There seems to be a trend towards using floating layers instead of popup windows. Floating layers (sometimes called "Div Popups" or "Floating Divs") are just HTML elements, such as a divs, styled to sit on top of the rest of the page. It's basically like a real window, and usually they are designed with an X in the top-right corner to let the user close the "window" (i.e. hide the layer).

There are some things to consider when deciding to use floating layers:

  1. Popup blockers don't block them
  2. People have to look at them at least to figure out how to close them
  3. If the user clicks a link on the page, the floating layer disappears with the rest of the page
  4. JavaScript is required to close them, but not necessarily to display them (popup windows require JavaScript for both)
  5. They will never look or act like real windows on every computer
  6. There is usually no way to minimize or resize them, or to switch back and forth between windows

If you think about it, each of these points could be a positive or negative. If you're displaying advertising, you'll be glad to sneak around popup blockers and force people to look at the thing. If you're designing a user interface, you might want to let people minimize, move and resize the popup window so they can see what is behind it.

From a usability perspective, floating layers are a bad idea. You have to design a way to close them, maybe even to move them around. But however you design them, they won't match everybody's desktop. Sure, you can design them to match the default Windows XP theme, but they will stick out like a sore thumb on Mac OSX. By using floating layers, you make people have to stop and think and figure out how to close the thing, whereas they would automatically know how to close a regular popup window without thinking.

There is already a very easy way to make a window that fits in with the rest of the operating system that can easily be moved, resized, minimized, maximized. Unless you have a strong need to use a floating layer, you might as well stick with window.open.

Published on June 26th, 2006. © Jesse Skinner

Rich Text Editing in Opera 9

This happened a few days ago, but I didn't think to blog about it until now for some reason: Opera 9 has been released. There are a lot of changes to it, the most notable (to me anyway) is the presence of Rich Text Editing, otherwise known as contentEditable or designMode. Click here for a demo and documentation. I've had a chance to play around with it and it works very well using existing code from Firefox and Internet Explorer. It seems there are some minor differences for really specific things, but overall I was suprised at how compatible it was right out of the box.

Now if only Safari's rich text editing could get this sophisticated...

There are other big changes that look great, but I won't bother listing them all here. Go take a look at the release notes for that.

Published on June 23rd, 2006. © Jesse Skinner

addDOMLoadEvent

Update March 2014: This code is now available on GitHub

There has been a problem with using window.onload in JavaScript. This event handler waits until all the images and other files load before executing. If you need some JavaScript to execute when the page loads, you usually only need the HTML to be downloaded, not all the images.

The event to use for this is "DOMContentLoaded", but only Firefox (and recently, Opera 9) support this. There are different ways to do this in every other browser, and people have been working on finding a complete solution to this for some time.

Very recently, this problem has been solved by Dean Edwards, Matthias Miller and John Resig. There is a unique solution for Internet Explorer, Safari, and for W3C-compatible browsers (Firefox and Opera 9).

Very soon after, Dan Webb adapted the solution to prototype. Unlike the original solution, this code allows you to add more than one function to be executed when the DOM loads.

Inspired by Simon Willison's addLoadEvent function, I wanted to create a standalone generic solution that anyone could use without needing a specific framework.

So here's the js file: adddomloadevent.js, and here's the actual code:

/*
 * (c)2006 Jesse Skinner/Dean Edwards/Matthias Miller/John Resig
 * Special thanks to Dan Webb's domready.js Prototype extension
 * and Simon Willison's addLoadEvent
 *
 * For more info, see:
 * http://www.thefutureoftheweb.com/blog/adddomloadevent
 * http://dean.edwards.name/weblog/2006/06/again/
 * http://www.vivabit.com/bollocks/2006/06/21/a-dom-ready-extension-for-prototype
 * http://simon.incutio.com/archive/2004/05/26/addLoadEvent
 * 
 *
 * To use: call addDOMLoadEvent one or more times with functions, ie:
 *
 *    function something() {
 *       // do something
 *    }
 *    addDOMLoadEvent(something);
 *
 *    addDOMLoadEvent(function() {
 *        // do other stuff
 *    });
 *
 */
 
addDOMLoadEvent = (function(){
    // create event function stack
    var load_events = [],
        load_timer,
        script,
        done,
        exec,
        old_onload,
        init = function () {
            done = true;

            // kill the timer
            clearInterval(load_timer);

            // execute each function in the stack in the order they were added
            while (exec = load_events.shift())
                exec();

            if (script) script.onreadystatechange = '';
        };

    return function (func) {
        // if the init function was already ran, just run this function now and stop
        if (done) return func();

        if (!load_events[0]) {
            // for Mozilla/Opera9
            if (document.addEventListener)
                document.addEventListener("DOMContentLoaded", init, false);

            // for Internet Explorer
            /*@cc_on @*/
            /*@if (@_win32)
                document.write("<script id=__ie_onload defer src=//0><\/scr"+"ipt>");
                script = document.getElementById("__ie_onload");
                script.onreadystatechange = function() {
                    if (this.readyState == "complete")
                        init(); // call the onload handler
                };
            /*@end @*/

            // for Safari
            if (/WebKit/i.test(navigator.userAgent)) { // sniff
                load_timer = setInterval(function() {
                    if (/loaded|complete/.test(document.readyState))
                        init(); // call the onload handler
                }, 10);
            }

            // for other browsers set the window.onload, but also execute the old window.onload
            old_onload = window.onload;
            window.onload = function() {
                init();
                if (old_onload) old_onload();
            };
        }

        load_events.push(func);
    }
})();

Update: I added a demo page, as well as a compressed version (only 876 bytes).

Update: Thanks to Adam Schlag's suggestion, I fixed the memory leak in IE.

Update: Thanks again to Rob Cherny and Alistair Potts, I've updated the solution so that it works over HTTPS without any security issues. I also decreased the compressed size to 761 bytes. Now it's perfect! (I hope!)

Update: I've gone back and reworked the code to get rid of the global variables, and I've managed to reduce the compressed size to 563 bytes!

Update [Aug. 19, 2007]: Now the script preserves any existing window.onload function, and also executes functions instantly when called after the page has already loaded. But now the compressed version is a hefty 617 bytes.

Published on June 21st, 2006. © Jesse Skinner

This site is now XHTML 1.0

I just did some interesting reading that made me rethink the purpose of the different versions of HTML.

One of the first things I did when I launched this site was work to convert it to valid XHTML 1.1. I was excited about the potential of HTML served as XML, and I saw the doctype of my site as a vote towards moving forward. The more sites that start serving XHTML, the faster browsers will support it, right?

Well that might be true, but the fact is, we're not there yet. As I've mentioned before, this is required for delivering XML applications, even XHTML. The problem is, Internet Explorer just doesn't support the application/xhtml+xml mime type.

Previously, I used a workaround to send XHTML 1.1 to browsers that could support it (ie. Firefox), and XHTML 1.0 to browsers that couldn't. This is what I've done for the past year.

Today, I read on the Mozilla website, in the Web Developer FAQ:

... if you are using the usual HTML features (no MathML) and are serving your content as text/html to other browsers, there is no need to serve application/xhtml+xml to Mozilla. In fact, doing so would deprive the Mozilla users of incremental display, because incremental loading of XML documents has not been implemented yet. Serving valid HTML 4.01 as text/html ensures the widest browser and search engine support.

Geez, I thought, what have I done? I tried to make things better for Firefox users, but really I just made things slower.

There are lots of benefits to serving HTML as XML. The thing is, the browsers do a better job just working with HTML at the moment, so if you don't require the benefits of XML, you're better off sticking with HTML.

I read another article, Sending XHTML as text/html Considered Harmful. So let's get this straight: it's harmful to send XHTML as either text/html or application/xhtml+xml. Since these are our only two choices, this means it's harmful to use XHTML! Since the browsers don't properly support XHTML, there's no tangible benefit yet to using XHTML instead of just HTML 4.01 strict.

One day there will be a reason to move forward and start using XHTML in all its glory. Many of us have been trying to make this a reality as soon as possible. Okay, it's a nice idea to start using XHTML 1.0 so that the transition in the future will be as smooth as possible. But beyond that, beyond looking into the future, there's no sense in changing what we're doing today. If a version of Internet Explorer ever comes out (8? 9? 15?) that really supports XHTML, then things might change.

Anyway, long story short, this web site is now XHTML 1.0, and I'm considering just going back to HTML 4.01 strict.

Published on June 20th, 2006. © Jesse Skinner

File formats of the future

After reading Tantek write about file formats, I've been thinking about what will happen to file formats in decades or centuries from now. Tantek says,

"I feel quite confident storing files in the following formats: ASCII / "plain text" / .txt / (UTF8 only if necessary), mbox, (X)HTML, JPEG, PNG, WAV, MP3, MPEG"

I agree, for the short term. But will JPEG be around in a hundred years? What about MP3?

I think we can make some assumptions about the future. For example, disk space will continue to grow and get cheaper, and bandwidth will get faster and cheaper as well. This leads me to think that compressed lossy formats will disappear. Why store in a JPEG when a PNG or even RAW format will do? Why store in MP3 when a WAV will do?

Okay, I don't think we will necessarily store in the least compressed format. I think we will use a format which uses lossless compression, so that the sound/image doesn't change at all. It won't make sense to lose quality to gain disk space anymore.

What about HTML? Oh, I don't know. This is a big question. The web is very new and it's not clear the direction it's moving in. We are using HTML, CSS and JavaScript in ways it was never intended to create desktop-style applications. I think application markup languages like XUL, XAML or even HTML 5 will take off where HTML leaves off, and we'll have no reason to continue abusing HTML the way we have been.

For hyperlinked documents, I believe (X)HTML will stay around for a very, very long time. CSS can grow and change and add display functionality on top of HTML. Put does HTML need to change? Do we need anything more than headers and paragraphs, with span or div tags together with classes to accomplish anything not built into HTML? I don't believe so.

It will be interesting to watch formats and standards evolve over the coming years and decades. I think one day, people will look back at these times with a smile on their faces, enjoying our naivety in these early years as we try to figure everything out.

Published on June 19th, 2006. © Jesse Skinner

Carnival of the Web #1

Welcome to the first monthly Carnival of the Web. Below you'll find some of the best posts from the past month in the web professional blogosphere.

The next Carnival of the Web will be posted on Sunday, July 23rd. If you write about web design or development and want to contribute something over the next month, feel free to submit your blog posts.

The infamous Roger Johansson of 456 Berea Street reminds us to Use Ajax scripting responsibly. Be sure to check out the comments to discover just how intense (and long) comments can get.

Mike Papageorge of the ever popular Fiftyfoureleven suggests some very clever and not-so-obvious ways to optimize the load time of a web site in Reducing HTTP Requests.

Andy Hume at Bite Size Standards knows that Understanding "Any order columns" is difficult. In this wonderful tutorial, he explains why the order of columns in HTML can be different from their order on the screen using CSS.

Emil Stenström, web developer extraordinaire at Friendly Bit helps us remember where we've come from, the mistakes we've made and why it's taken us so long to start using standards again. See why Real hackers don't use CSS.

Dustin Diaz takes a different side in the ongoing debate and answers the question Why inline styles with strict doctypes?

Joe Kissell of Interesting Thing of the Day explains just what is so interesting about Cascading Style Sheets in the first place, with Cascading Style Sheets / Bringing sanity back to Web design.

At RotorBlog, Maris does a side-by-side user interface comparison of two similar personal web portals in Netvibes vs. Pageflakes - design and basic functions.

Artem points us over to Solution Watch to check out a review of something that should keep you distracted from work Up for Ajax Battleship? Play Sink My Ship.

Ohad of Ohad's Internet News offers a new way of writing blog posts that is an ongoing process reacting to user feedback in Evolutionary posts.

Craig at gridbuzz goes below the headlines on the Net Neutrality issue to explain What Net Neutrality is really all about.

Jon Swift takes a look at his recent Google Searches and realises that if the government is watching him, they're going to be in for a surprise.

And last but not least, Chris Quimby shares a humorous tale of helping his mother onto the information superhighway with Throwing Mom on the Highway.

Published on June 18th, 2006. © Jesse Skinner

Cleaner Callbacks with Closures

Dan Webb at The Web's Bollocks has posted a great article, Cleaner Callbacks With Partial Application. It describes ways to use JavaScript closures to keep your code cleaner and more reusable, especially when creating XMLHTTPRequest callbacks. If you understand the basics of closures but want to see some practical applications, go check it out.

If you're new to closures or have been struggling to understand how they work, I recommend reading Mark Wubben's introduction, Getting Funky With Scopes and Closures. For a more detailed and thorough analysis, be sure to read Richard Cornford's JavaScript Closures.

Published on June 13rd, 2006. © Jesse Skinner

Random SEO success

In November, I put some tools written in JavaScript on here. These are mostly conversion tools, things like pounds to kilograms, kilometers to miles, etc.

I had the idea of coding and hosting some random JavaScript things on here, but since then I haven't added anything.

Then I forgot about them.

Now, I get most of my traffic on these conversion tools. As of recently, if you search millimeters to inches on Yahoo!, my site is #1. Because of this, I've gotten a whack of traffic just on this one page.

I wonder what it is about that page that Yahoo! considers so special. There aren't even any sites that link to it. It's really some kind of SEO marvel.

Published on June 12nd, 2006. © Jesse Skinner

Last Call for the Carnival of the Web

This is a last call for submissions to the first monthly Carnival of the Web. Saturday, June 17th is the deadline, as the carnival will be posted here on Sunday.

So if you have a blog that web professionals would be interested in, or if you've read something really great on another blog in the past month, please make a submission.

Published on June 11st, 2006. © Jesse Skinner

Yahoo! figures it out

When early versions of Internet Explorer 7 were released, it was clear that IE would now have a search toolbar like Firefox. It was also clear that this would default to use MSN, rather than the Firefox default of Google. Google freaked out and tried to sue Microsoft, but the Justice Department said it was OK and prevented Google from doing anything about it. Google's strategy was to continue to promote Firefox, as well as give instructions to IE 7 users on how to change their default search engine.

Now, Yahoo! has released a customized version of IE 7 beta which presets the homepage and search bar to Yahoo!. Rather than fight the beast, they've embraced it and made things even easier for people who still prefer Internet Explorer. Good move, Yahoo!.

Disclaimer: I only use Internet Explorer for testing. Firefox is definitely the way to go for day-to-day surfing.

Published on June 10th, 2006. © Jesse Skinner

The Timely Web

Did you ever own a directory of the web? Like this big yellow pages book with every known web page on the Internet? I did. I never used it. I guess I skimmed through it, but it was very soon out of date. Not only were half the links gone, but there were so many new sites that just weren't included. The thing is like an antique now. It'll probably be in a museum one day.

A few years later, the web got bigger and bigger. Soon it was too big to be navigated by a book, and of course search engines took over. The web was filled with many new web pages, most "Under Construction", and we were told to "Check back soon". Still, it felt like we could conceivably read the whole Internet if just given enough time. What we didn't consider was that the growth of the Internet would never stop.

Now look at where we're at. It's impossible to stay up to date on the 10 or 100 or 1000 web sites we visit without using RSS feeds. Thanks to technorati, we can see what others are saying about a topic in nearly real time. We've been forced to give up trying to "surf" the whole web, and have mostly settled down into our niches with barely enough time to do even this.

With so much information to choose from, only the very newest is often paid attention to. When you arrive at a new site, or subscribe to a new blog, do you take the time to read all the old posts? Or do you just sign up and look forward to the next posts, the newest stuff. I know I rarely have time to go back and read older stuff.

The Internet is indeed a giant repository of information, but the way many of us are using the Internet is changing along with the web itself. The blogosphere isn't just a sign of the personal web, it's also a sign of the timely web. We're less interested with what others have said about a topic, now we want to know what they've said about it lately.

Published on June 5th, 2006. © Jesse Skinner

I'm not a designer

You may not even notice right away, but I added shading to the boxes on this site. This is the final product of over three hours of working on my design.

No, I didn't struggle with making shading images for three hours. I tried to redesign my whole site from scratch. I'm getting a bit bored with seeing the same thing for over a year, and I've been told at least once that my design needs an overhaul.

I messed around with some different layouts and different looks, and some of the changes seemed good. One of my strategies was to put the side boxes with links to the bottom of the page. Although it did look a bit better and cleaner, I didn't want to lose the navigation "above the fold". I think when visitors come for the first time, these links may be the only reason they stick around.

Of all the experimenting I did, one thing was clear: I need to introduce images to add another dimension to this design. I decided that I could do this to the current design. So I did. And that's why I made the shaded boxes.

I think that rather than redesign the whole site, I'll continue to make minor improvements, move things slightly, add images, change the colours, rework the header or footer, etc. It's just too much to redo the thing from scratch, and then I'd lose all the work I've done so far.

Let me say it again in case it's not brutally obvious: I'm not a designer. I don't consider myself a designer. I have always been interested in art, and I like to draw and paint. I also know CSS inside and out. I think I know good design when I see it. But I'm no photoshop ninja. I have ideas in my head, but by the time I'm "finished" I'm looking at an ugly cheap pile of crap. This is an area I'd like to improve, but for now it's just a bit of a hobby.

Many people don't get the difference between a web developer and a web designer.. "Wait, we still have to pay someone to draw the thing? So what do you do exactly??" So maybe it would be in my best interest to tackle some web design.

If any designers out there want to pass on some tips on how to improve or which sites can teach me the tricks, I'd be very grateful.

Published on June 3rd, 2006. © Jesse Skinner

ppk on JavaScript

I just wanted to give a quick congratulations to Peter-Paul Koch of QuirksBlog. He just finished a JavaScript book, ppk on JavaScript. Way to go! If you're interested in learning more about JavaScript, or, as ppk said,

if you want to congratulate me, buy the book.

Update: You can pre-order the book at Amazon.

Published on June 2nd, 2006. © Jesse Skinner

Faster than you thought

Seth Godin gives another example of the Internet leveling the playing field. This time it's a girl named Emily finding success selling her artwork online. Seth says:

[This] should be proof to you that the whole thing is raveling (which means the same as unraveling, in case you were curious). That all the systems that kept all the processes in place and leveraged mature industries and experienced players are slowly (or quickly) filtering to the masses. Faster than you thought it would happen.

Just the other day, I saw on the CBC National a piece about a Canadian comedian, Russell Peters, who struggled to find an audience. Thanks to Google Video, his popularity has had an enormous boost. When asked about the effect of the Internet, he just said something like "that Internet thing.. I don't understand it but.. it's crazy."

Indeed, the Internet is already a place where individuals can reach wide markets and find success on their own, without the need for traditional media, Hollywood, television producers or other people in suits. The old system was great at producing one-hit-wonders that everyone liked and nobody loved. Now, there is room for everyone to find their own market, their own audience, their own place in the world.

Published on June 2nd, 2006. © Jesse Skinner

Unobtrusive JavaScript

You might have heard of unobtrusive JavaScript, but what the hell is it? Well, it's the separation of all your JavaScript from your HTML. That means putting all your JavaScript either in a <script> block, or even better, in an external file.

Why bother? Yes, sometimes it's easier to put JavaScript into onclick or onload attributes. But it's better to separate your content (HTML) from your presentation (CSS) from your behaviour (JavaScript). It keeps your HTML clean. It also makes things easier to maintain.

It's not just about the physical separation of JavaScript from HTML. It's the absolute separation. Your HTML should work without JavaScript. For example, if you have an empty <body> tag, and then attach use Ajax to pull content from the server and stick it into the body, that sucks. If somebody comes to your site without JavaScript (ie. the Google spider), they will get an empty page.

It's important that your whole site works without JavaScript. This way, your content can be used by people without JavaScript. Google's spider doesn't support JavaScript (to my knowledge). So, if you want your content to be indexed, make sure your HTML content can stand alone without JavaScript.

Unobtrusive JavaScript means adding JavaScript functionality on top of an already functional HTML site. This improves things for those with JavaScript without taking anything away from those without. Let's look at some simple examples.

The onload attribute on the <body> tag is popular. Instead of doing this:

<script>
function myLoadScript() {
   // do fancy stuff
}
</script>

<body onload="myLoadScript()">

you can just do this:

<script>
window.onload = function () {
   // do fancy stuff
}
</script>

<body>

There's no difference in functionality, but it does let you put your script in another file and have less stuff in the HTML. This way, you can change or remove your onload function without changing the HTML.

Here's another example. Let's say you have some JavaScript in a link to launch a popup window:

<script>
function showPopup() {
    window.open('myPopupPage.html',null,"width=600,height=400,toolbar=no");
}
</script>

<a href="javascript:showPopup()">I love popups!</a>

If somebody doesn't have JavaScript, this won't work. That sucks. You can do this instead:

<script>
function showPopup() {
    window.open('myPopupPage.html',null,"width=600,height=400,toolbar=no");
    return false;
}

window.onload = function () {
   document.getElementById('popupLink').onclick = showPopup;
}
</script>

<a id="popupLink" href="myPopupPage.html" target="_blank">I love popups!</a>

If somebody doesn't have JavaScript, they'll still get the normal link popup from the HTML alone. You won't be able to customize the size, toolbars, etc. but at least it will still partially work.

Notice that the showPopup() function now returns false. This will stop the page from doing what it normally does when you click the link. In other words, you'll only get the JavaScript popup, not two popups.

This technique can be applied to more complex JavaScript including Ajax techniques. If you have a form that is submitted in the background, and uses JavaScript to redraw the page without refreshing, great. Just add this functionality using JavaScript alone. Make sure that without JavaScript, the form just submits and the page refreshes the old-fashioned Web 1.0 way.

I will quickly mention something to silence those who are screaming at their monitors. document.getElementById doesn't work in every browser (like Internet Explorer 4 or Netscape 4), so you may want to use object detection to make sure it's supported. My policy is that if someone is using an older browser, they get the same thing as if they had JavaScript turned off.

I hope these techniques will help you to create wonderful, clean, sexy and modern unobtrusive JavaScript. Have fun!

Published on June 2nd, 2006. © Jesse Skinner

Blog Tipping

Joe at the Working at Home on the Internet blog just blog-tipped me, so I thought I'd pass on the Link Love. The idea of Blog Tipping is that on the first of the month, you pick three blogs you read and offer 3 compliments and 1 tip. So here goes.

gapingvoid

  1. I love that you've gone back to drawing cartoons full force. It's great to see people doing what they love.
  2. Your Microbrand concept is an inspiration to people everywhere who are trying to understand and find their place in this Internet-based economy.
  3. I'm really impressed with your work for Stormhoek. Even though you're alone on the frontier of marketing you're doing a great job.

tip: Perhaps it's a result of your busy schedule, but I'd like to see more longer posts with more of your thoughts and less links now and then.

Friendly Bit

  1. While no other web dev blogs seem to be discussing real, tangible web development concepts, yours just keeps on sticking to the point. That's a real inspiration for me.
  2. Your topics always give me something I can use right away, change the way I look at something, or give me something I know I'll be able to use in the future.
  3. I love how simple and straightforward your design is, with just a few categories and comments along the side.

tip: This is hard. I'd love it if you posted more often, but not if this degrades the quality of your post. Otherwise, just keep doin' what you're doin'.

Fiftyfoureleven

  1. Your topics are always very interesting, often addressing a topic in a new way that just isn't done often enough.
  2. You always have a great sense of humour (even if some of your readers don't understand it).
  3. Your design is really great, just barely bordering on Web 2.0 without crossing over. :)

tip: Start posting again! Two in the past three months?! You used to be almost daily!

Okay, now you all have to pass the link love on.

Published on June 1st, 2006. © Jesse Skinner

Microformats Search and Pingerati

Tantek Çelik has just announced the release of Technorati's Microformats Search! Tantek has been the pioneer and mastermind behind microformats. So far, the use of microformats was forward looking, like "One day there will be tools that search the web for microformats, and then all the hCards and hCalendars we're implementing will be useful." Well that day has finally come! Now you can search all the hCards, hEvents and hCalendar objects scattered around the web.

Also significant is the announcement of Pingerati, a ping service to announce the existance of microformats on pages Technorati isn't already indexing with rss (ie. an About page). Yet another useful tool in the microformats toolbelt.

Congratulations, Tantek, and thanks for such a great tool!

Update: Tantek has given a list of acknowledgments and thanks to all the other microformat searches and utilities that others have created thus far.

Published on June 1st, 2006. © Jesse Skinner