Archive for the ‘Rants’ Category

The Label Element

Friday, December 11th, 2009

Dear Web Developers,

The following mark-up is commonly used to put text adjacent to an input element such as a radio button or check box:

<input name="foo" type="checkbox" value="bar" /> Click this checkbox.

DO NOT DO THIS!

Instead wrap put the text next to the check box inside the label element and give the input element an ID the label element can reference. e.g.

<input id="foo" name="foo" type="checkbox" value="bar" />
<label for="foo">Click this checkbox.</label>

This allows for the user to click on the text to interact with the input element as well as clicking just on the input element itself increasing usability of your sites and applications and subduing my rage.

Please don’t destroy browser functionality

Sunday, July 12th, 2009

Dear web developers,

Please consider browser functionality when designing your sites. More and more “Web 2.0″ sites are taking away my browser features. The biggest culprit so far are sites with JS that like to make links which redirect you to a different page via JS or pop-up a modal, or other similar dialog which then has a link that takes you to a different page. Both of these prevent me from being able to open a link in a new tab, which is more than annoying. My university and several large shopping sites still do this. Please stop.

If I middle click a link which, if I left click it takes me to, or has another link which takes me to, another page, that action should open that page up in another tab. Repeat: that action should not do nothing, but open the page up in a new tab! It also should open the link and not something like the same page with a # appended to it or some Javascript in the address bar.

The danger of using frameworks that augment default objects

Monday, July 6th, 2009

After a bit of thought it occurred to me just how dangerous using frameworks, like Prototype, which augment built-in objects in large-scale production projects.  As many avid JS developers are most likely aware, the prototype inheritance model of the language allows for the extension of virtually any object in the language, user defined or otherwise. However, this can also have severe side effects if a browser developer decides to include a method of the same name as your framework of choice added to a built-in object some years back.

Take, for example, the venerable each function. Prototype extends enumerable objects such as arrays with this function in its prototype. e.g.

Array.prototype.each = function(f){

   var i = 0;

   for(; i < this.length; i = i + 1){

      f(this[i],i);

   }

}

Now imagine this code is called in thousands of places in your project. Let’s also assume before extending the object prototype such a library would also check for the existence of said function as to not overwrite default behavior e.g.:

if(!Array.each) {

   …

}

Now imagine an A-grade browser’s newest version now includes the each method on collection objects by default but with either an argument omitted, or the argument order swapped. All of the code that you had written that depended on the augmented each function instead of the built-in each function will now no longer work in that browser, and you can’t very well force users to not use the latest version of IE, Safari, Firefox, or Opera because a decision was made some years back to use a framework which augments built-in objects.

This decision may now cost many thousands of dollars, if not more. Other JS frameworks such as YUI or jQuery seem like a much more sound choice in this respect. In my opinion, YUI is probably the better of the two choices as it is far easier to pick-up and master by developers of other, not necessarily web-centric languages. Yet in the scope of this rant, both are equally more sound than using something which could very easily and most likely inevitably break a few years down the road, costing many unnecessary man-hours, and perhaps dollars, to fix.

Why do I have to fill out the exact the form…

Sunday, March 15th, 2009

This is the 21st century. Virtually everybody has some sort of computrized database for storing contact or other meta-personal information and yet anytime I change my address (e.g. physical, e-mail, IM, phone number, etc.) or some other piece of information (e.g. credit card, insurance carrier, etc.) I have to send out  e-mails, make phone calls, fill out a change of address form at the post office, call creditors and banks, inform family and friends, or something equally painful and mind-numbing about a few dozen times. This is bizzare.

It would be much better if we had something like a DNS system, but for people instead of IP addresses. This type of system can work transparently on top of already existing systems. I haven’t really hashed out all the details of this but it would work something like this:

You give whoever you want to be able to contact you or know some information about you some identifier. They then use this identifier for everything related to you. So when they want to write you an e-mail they put in this identifier and their e-mail client requests your e-mail address from the system given that identifier and then sends the e-mail to that address. If you change your address at a later time, then the next time that identifier is used it will automatically follow you. The same goes for phone systems, chat systems, physical addresses etc.

Although it would make usability a bit clumsy a security layer could be added using public-key cryptography. So when you give out your identifier they also give out theirs. Then you log-in to a central system and authorize their identifier for only certain parts of your data, or perhaps slightly different data than you give out to others (e.g. you authorize a shady site for the e-mail address myspam@mydomain.com instead of myemailaddress@mydomain.com that everyone else gets). That way you can only give out the information you want to give out. Then at any time you can change or update your information and authorize/deauthorize keys to access that information.

Essentially this kind of system would remove the need for filling out multiple change of information forms and making multiple calls, e-mails, IMs, etc. You would just go into the system, update your info, and it would get propogated out the next time it is requested. No more change of address forms, everything just follows you if you want it to, and stops when you don’t.

Internet Explorer, Tables, the DOM, and what not to do…

Saturday, March 14th, 2009

A post on reddit a few weeks ago finally inticed me enough to sign up for an account on the popular social link sharing site. The post was at a blog by Eric Vasilik (who supposedly had something to do with making IE a horrible platform to develop for) that dealt with having to insert the new rows into an existing table. Intuitively, most coders would just use the .innerHTML property and go about their day until they later test their code in IE and then everything explodes because IE doesn’t play nice when it comes to tables and .innerHTML. Especially when inserting new rows. What really irked me about the whole thing though was the way Mr. Vasilik was going about solving his problem.

For reasons beyond me Mr. Vasilik decided that it would be best to not just use the DOM methods and insert rows in that manner. Instead Eric wrapped his newly created HTML for table rows inside of <table> and <tbody> tags, put them into a hidden element on the page, and then looped over rows in the currently visible table calling the replaceChild method on the table in order to swap out the rows. This solution does, in fact swap out all of the rows. Unfortunately it is painfully slow.  Having to use the DOM alone for this is already significantly slower than using innerHTML (but IE makes this impossible, at least for versions 7 and lower) but using both innerHTML and the DOM is even slower than that. Instead of creating the table rows as strings Mr. Vasilik should have JSON encoded the tables so that he would’ve had them as objects after a quick eval or if he had to create them in the code then he should’ve used the DOM to create the objects and used insertRow, insertCell, etc. on the table object instead of using the least efficient approach he could think of.

I ended up writing a few speed tests to test innerHTML, DOM, DOM/appendChild, and DOM/innerHTML/replaceChild which can be found here (needs Firebug to run).  Not surprisingly, using innerHTML to create a new table, then calling replaceChild to swap table rows was the slowest of the tests. Full code below:

(function()

{

var table = document.getElementById(‘test’);

var tr, td;
<pre id="line1">  console.time("DOM Manipulation");
  for(var i = 0; i &lt; 1000; i++)
  {
      tr = table.insertRow(-1);
      td = tr.insertCell(-1);
      td.innerHTML = "Test";
  }
  console.timeEnd("DOM Manipulation");
  table.innerHTML = "";
  console.time("innerHTML");
  var rows = "";
  for(var i = 0; i &lt; 1000; i++)
  {
     rows += "&lt;tr&gt;&lt;td&gt;test&lt;/td&gt;&lt;/tr&gt;";
  }
  table.innerHTML = rows;
  console.timeEnd("innerHTML");
  table.innerHTML = "";
  console.time("DOM, appendChild");
  for(var i = 0; i &lt; 1000; i++)
  {
    tr = document.createElement("TR");
    td = document.createElement("TD");
    td.innerHTML = "Test";
    tr.appendChild(td);
    table.appendChild(tr);
  }

  console.timeEnd("DOM, appendChild");
  rows = "&lt;table id=’test2′&gt;";
  console.time("DOM, span, replaceChild");
  for(var i = 0; i &lt; 1000; i++)
  {
    rows += "&lt;tr&gt;&lt;td&gt;test DOM, span, replaceChild&lt;/td&gt;&lt;/tr&gt;";
  }
  rows += "&lt;/table&gt;";

  var spanTemp = document.getElementById("temp");
  spanTemp.innerHTML = rows;
  var varTempTableRows = spanTemp.getElementsByTagName("table")[0].getElementsByTagName("TR");
  for(var i = 0; i &lt; varTempTableRows.length; i++)
  {
     table.replaceChild(varTempTableRows[i], table.childNodes[i]);
  }
  console.timeEnd("DOM, span, replaceChild");
})();

UPDATE: Seems like this completely changed in FF3.5 and using innerHTML is significantly faster than any of the previous methods.