Stefan Hayden

Alt + Shift + Ctrl + K
Archive for the 'design' Category

For Books I Am Reading I have been usingĀ Get Satisfaction for keeping in touch with my users. It’s worked out pretty well and kept me from having to build anything myself.

Now they have released a widget that puts a “feedback” tab on the left of every page and brings up a lightbox where they can send feedback right from the page. Sounds like a cool idea and I’m up for trying it for a little while at least.

Being a bit crazy when it comes to how I want Books I Am Reading to look I’m not sure I love having that black tab on the left. The site is pretty sparce and I’d like to keep it that way. Originally I thought I would just put the widget where ever I wanted it to go. I figured it would be a good addition to the 404 page. Sadly that is not an option but perhaps it will be one in the future.

If I get more engadment out of the community I’ll think about keeping it around. But if not then I will most likly take it off and keep the design as minimal and clean as possible.

Hopefully we are just a year or two off from css being this easy.

If you’re not using Smush.it download it now. No respectable web designer can avoid this amazing firefox extension.

Smush.it strips out all the extra data that photoshop leaves in. None of the data effects the visual quality of the image. A quick survey of my sites show that PNG files created by photoshop can save from 25 to 50% of their files size. INSANE!

What kind of saving have you gotten from your sites?

These Obama shirts must be selling really well cause everyone is making them at this point.

Obama Tshirt

SugarLoot’s redesign was launched the other day. Wiping out most of the work I have done at Sconex. Most of my code and user interface is still there but the look and feel is very different.

Books I Am Reading is tiny site I created to experiment with design and track my reading. With small sites come small mile stones and I’m very excited to have my 1,000th account created.

The community is still very small. Only about 25% of accounts created have added a book. And only 10% have added several books. I’ve talked to several passionate users but I would guess there are no more then 20 or 30 users who use it as a way to truly track their reading.

But for a small web site with many bugs still present this is extremely gratifying.

Justine Larbalestier was confused about why you would care what font you wrote something in. There are some very good comments but this is what I had to say:

For the most part any font you can read will do. But a lot of authors do talk lot about the experience of writing. Some find writing in certain places make it more enjoyable or even helps them produce a different quality of work.

Lot of authors yearn to write a novel on an old typewriter to get the feel of how those old timey writers did it.

I posit that the font you chose can have a similar effect. Perhaps if you like listening to music to set your mood you might want to chose a font that better reflect the type of mood you are trying to give. Some fonts are contemporary and some classic. Some are airy and light while some are dark and foreboding.

I’m not saying it will get you any different results but enough authors seem to talk about setting up the experience of writing that it must have some effect for some people.

via Keri

Update: jdalton has what looks like a great improvement on my attempt below. Read below to learn about the problem but look at jdalton’s script to see what is now the current best way to implement a solution.

Update (August 5th, 2008): There was an update to the JavaScript below to better handle IE firing off the ready state.

Warning!: Due to a Prototype bug This code is not reliable in any version of IE. This bug is expected to be fixed in Prototype 1.6.0.3.


So the YUI blog had a great post on how javascript blocks downloads and makes the page take longer to load. This is because any JS file can modify the DOM and so the DOM can’t be ready until all JS files have loaded.

Flugpo uses Prototype and not YUI and so to get the speed benefits I needed to build my own Bells and whistles. The problem is that once you load the JS files asynchronously any onDOMReady function will fire before all the JS files download. This is a problem for any inline function calls that have dependencies on other JS files.

Using the Prototype based onDOMReady extension I have created an onJSReady function that checks that all JS files have been loaded. The function needs to know 2 things. How many JS files there are and how many have currently been loaded. When those two number match the even fires and runs any code that is waiting.


/**
 * A modified version of Stefan Hayden's onJSReady Prototype plugin. 
 * http://www.stefanhayden.com/blog/2008/07/29/javascript-event-onjsready-fires-when-all-js-files-have-loaded/
 *
 * @author John-David Dalton 
 * @usage
 *   Prototype.include(['test1.js','test2.js','test3.js']); // array
 *   Prototype.include('test1.js', 'test2.js', 'test3.js'); // separate arguments OR
 *   Prototype.include('test1.js,test2.js,test3.js');       // comma separated string OR 
 *
 *   document.observe('scripts:loaded', function(){ dependent_on_external_js() });
 */
Prototype.include = Object.extend(
  function() {
    var callee = arguments.callee,
     head = document.getElementsByTagName('HEAD')[0],
     args = Array.prototype.slice.call(arguments, 0);

    args._each(function(files) {
      if (Object.isString(files))
        files = files.split(',');
      
      callee.total += files.length;
      files._each(function(file) {
        head.appendChild(
          new Element('script', { type: 'text/javascript', src: file.strip() })
        )
        .observe('readystatechange', function () {
          if (!this.loaded && /^(loaded|complete)$/.test(this.readyState)) {
            this.loaded = true;
            callee.downloaded++;
          }
        })
        .observe('load', function () {
          if (this.loaded) return;
          this.loaded = true;
          callee.downloaded++;
        }); // end observers
      }); // end files _each 
    }); // end args _each
  }, 
  {
    total: 0,
    downloaded: 0
  }
);

(function() {
  var timer;
  function ready() {
    if (arguments.callee.done) return;
    clearInterval(timer);
    arguments.callee.done = true;
    document.fire('scripts:loaded');
  }
  
  timer = setInterval(function() {
    var i = Prototype.include;
    if (i.total && i.downloaded === i.total) ready();
  }, 10);
})();


This is old... ignore this.
window.Total_JS_Files;
window.Downloaded_JS_Files = 0;

function include_js(files) {
	var js=new Array();
	window.Total_JS_Files = files.length;
	
	for(var i=0; i < files.length; i++) { 
		
	    var html_doc = document.getElementsByTagName('head')[0];
	    js[i] = document.createElement('script');
	    js[i].setAttribute('type', 'text/javascript');
	    js[i].setAttribute('src', files[i]);
	    html_doc.appendChild(js[i]);
	
	    js[i].onreadystatechange = function () {
	        if (js[i].readyState == 'complete') {
	            //alert('JS onreadystate fired ');
	            window.Downloaded_JS_Files += 1;
	        }
	    }
	
	    js[i].onload = function () {
	        //alert('JS onload fired ');
	            window.Downloaded_JS_Files += 1;
	    }
    }
    return false;
}//include_js


Object.extend(Event, {
  timeout : function() {
	alert('asd');
  },
  jsReady : function() {
  
    if (arguments.callee.done) {return;}
    arguments.callee.done = true;
		
	Event._NreadyCallbacks.each(function(f) { f(); });
	Event._NreadyCallbacks = null;
		
  },
  onJSReady : function(f) {
    if (!this._NreadyCallbacks) {
      var jsReady = this.jsReady;
      
      if (jsReady.done) {return f();} 
        
		function jsTest() {
			if(window.Downloaded_JS_Files == window.Total_JS_Files) { 
				//setTimeout(jsReady,1);
				jsReady();
			}
			Event._Ntimer = setTimeout(jsTest,1); 
		}
		Event._Ntimer = setTimeout(jsTest,10); 
        
        //Event.observe(window, 'load', jsReady);
        Event._NreadyCallbacks =  [];
    }
    Event._NreadyCallbacks.push(f);
  }
});
  

To implement this the only JS that needs to load is prototype and these two functions above. Then you just need to load the URLs for the JS files and fire off the include_js function.


var js_paths = new Array;
js_paths[js_paths.length] = '/path/to/js/one.js';
js_paths[js_paths.length] = '/path/to/js/two.js';
js_paths[js_paths.length] = '/path/to/js/three.js';

include_js(js_paths);
Prototype.include(js_paths);

Once all of the JS files have loaded then just like onDOMReady the onJSReady code will fire.


Event.onJSReady(function () { dependent_on_external_js(); });
 document.observe('scripts:loaded', function(){ dependent_on_external_js() });
 

jsmap is a pretty awesome region select. I think what we have for Flugpo is a better option for us but if we only needed to pick states I would really want to use jsmap.

If you need a video, a 2:47 minute video, to show people how to register then it is TOO HARD to create and account (video below).

wow.. I really hate the new google favicon. It’s a lot more generic and harder to recognize. And what’s up with the horrible purple color? And the horrible shine!

FireFox 3 RC1 has some small but good updates from the beta 5 version. One of the biggest eye sores was fixed in the auto complete url bar. The typography and color make it much more organized and easier to read. The little design changes always make me happy.

History Of The Color Wheel. very in depth.

NYTimes.com hand-codes its HTML. Why in the world is this so news worthy? I hear the Times also pays writers for stories and the sky is blue.

My best guess is that this might be the crossover moment for non web organizations. To date when most people think of web designers they think of dreamweaver. Perhaps now companies will start demanding hand coding designers. But who knows.

I fall for something every year but if this is real then it’s the worst logo redesign in the history of the world.