Coding with Jesse

Carnival of the Web #2

Welcome to the second edition of the Carnival of the Web.

To start things off, Emil Stenström at Friendly Bit brings up some good points with Current issues with Microformats.

John Oxton makes us web developers all feel a little bit better about ourselves with No I am not bloody sorry.

Rob Cherney follows up on John Oxton's post (and makes us feel even better) with A Bloody Good Developer.

Justin Palmer at EncyteMedia gives a different way of looking at design issues with Unconscious Interface Design.

Clay Mabbitt of Web Design Businesses Best Practices gives a nice guide to Pricing your web design service.

Joe Kissell at Interesting Thing of the Day gives us an introduction to Wikis.

Ohad's Internet News referees the battle of the giants with Google VS Microsoft.

Gerard at Interweb World wants to help you Perfect Your WordPress Title Tags.

George Papp at the Website Auction Hub answers the question How can I monetize my forum and start making money with it?.

Daniel Scocco of Innovation Zen outlines the top 5 trends of Marketing Under the Information Age.

And finally, Daniel Swiecki wonders what comes after Web 2.0 by asking How Much Rounder Can Corners Get?.

Published on July 23rd, 2006. © Jesse Skinner

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
<< older posts newer posts >> All posts

Contact Jesse

Need help with a project? Any questions about my writing? I'd love to hear from you.

Email me at [email protected]