Skip to content
spacer

»My latest delicious finds

Content starts

The only for loop you will ever need *

* main contain hyperbole to take the mickey out of other blog posts

I am a very lazy person when it comes to typing. As I am doing so much of it I’d rather not type something I really don’t need. This is why I had an issue with “for” loops as you need to type them so often.

The classic way of looping through an array for example is a for loop with an iterator:

var arr = [1,2,3,4,5];
for( var i=0; i<arr.length; i++ ){
  alert( arr[i] );
}

This is however not a good plan for large arrays (like DOM trees) as the length attribute is read out every time the loop executes. You can avoid this in two ways. If it is for example irrelevant in which order you loop through the array you can use a reverse loop:

var arr = [1,2,3,4,5];
for( var i=arr.length - 1; i> -1; i -- ) {
  alert( arr[i] );
}

If you really need to go through the array in the normal order then you need to use another variable to store the length and compare with that one.

var arr = [1,2,3,4,5];
for( var i=0,j=arr.length; i<j ; i++ ){
  alert( arr[i] );
}

The for loop also allows you to use the in keyword to make it easier:

for(i in arr ){
  alert(arr[i]);
}

However, there is also another trick if you don’t want to do this (for example if you don’t want to iterate through all but use a step of 2). The comparison inside the loop does not need to be the iterator but could be any comparison. As long as it is true, the loop gets executed, when it becomes false the loop ends. This allows you to simply check for the array element inside the loop itself which means you don’t need to read the length attribute at all:

var arr = [1,2,3,4,5];
for(var i=0; arr[i]; i++ ){
  alert( arr[i] );
}

There is however the issue of the truthy and falsy and type casting in JavaScript which means that if your array has null or 0 elements the loop would end, too:

var arr = [1,2,0,4,5];
for(var i=0; arr[i]; i++ ){
  alert( arr[i] );
}

You can avoid this by testing properly:

var arr = [1,2,0,4,5];
for(var i=0; arr[i]!==undefined; i++ ){
  alert( arr[i] );
}

There is also another problem this kind of loop avoids: if you manipulate the array during execution of the loop (for example by removing or moving DOM nodes) you need to change the iterator, too. This example will be an endless loop and lock your browser:

var u = document.getElementsByTagName('ul')[0];
var lis = u.getElementsByTagName('li');
for( var i=0; i<lis.length; i++ ){
  u.removeChild(lis[i]);
}

With the other kind of loop that is not a problem. You can for example remove all list items from a UL with:

var u = document.getElementsByTagName('ul')[0];
var lis = u.getElementsByTagName('li');
for( var i=0; lis[0]; i++ ){

u.removeChild( lis[0] ); }

Did I miss something obviously bad about this idea? If so, please tell me, but also consider the other benefits of this for loop to end all for loops:

  • a lot smaller than the YUI, Dojo or Prototype
  • unobtrusive and accessible (if the array is not there nothing happens)
  • may have rounded corners (but they are invisible)
  • cross-browser
  • easy to read
  • heals sick animals when you don’t look

If you wonder about the speed implications of the different styles, check out the speed comparison of for loops test page.

Technorati Tags: for, loops, javascript, optimization, comparison, webdevtrick

Digg this | Add to deli.cio.us | Technorati
Chris @ 4/2/2007 / 10:03 pm filed under: General
2 comments

Q&A: Linking a whole DIV

Q: I have a DIV with some text, an image and a link and I was asked by our designer to make the whole thing a link. I cannot use an image, so I tried nesting all in a link and making the real link text a SPAN with a style that makes it look like a link, which seemed dirty and I used a link around a DIV which is invalid HTML. How can you link a whole DIV?

A: This is a classic example where a small JavaScript makes a lot more sense than trying to misuse HTML or make non-semantic HTML mimic the proper element with CSS. If your construct is something like <div><img ... /><p> ... <a class="foo.html">foo</a></p></div> you can write a JavaScript that assigns a click handler on every DIV that changes the document location to the href attribute of the first link:


window.onload = function(){
  var divs = document.getElementsByTagName('div');
  for(var i=0,j=divs.length;i<j;i++){
    if(divs[i].className === 'clickbox'){
      divs[i].onclick = function(){
        window.location = this.getElementsByTagName('a')[0].href;
      }
    }
  }
}

This is a rather obtrusive example when it comes to event handling, but it should get you on your way.

Technorati Tags: netmag, netmaguk, css, linking, javascript

Digg this | Add to deli.cio.us | Technorati
Chris @ / 5:11 pm filed under: General
Add a comment

Q&A: Dynamically assigning CSS Floating in JavaScript

Q: I am creating some HTML elements using JavaScript and the DOM. All is fine, but I need to define one element as floated to the right. I tried var d=document.createElement(‘div’); d.setAttribute(‘float’,’left’); which seems to do it, but the element is not floated. I tried then to use the style collection with d.style.float = ‘left’; but that didn’t work either. How do you float an element in JS?

A: Your first approach was wrong, as this would add an attribute called “float” to the element and not set the CSS property. The second approach is almost right, but “float” is a reserved word in JavaScript (because of floating point numbers). The correct property of the style collection is called cssFloat (you will also run into the same issue when you try to create labels with a “for” attribute, this one is called htmlFor). This’ll work nicely in Firefox, but Internet Explorer does not support cssFloat (one of the annoying bugs that were still not fixed).

In any case, generating a lot of HTML and defining the style inside your JavaScript is not a very maintainable way of development. It is much easier to keep the annoying little browser CSS support glitches to fix in CSS rather than having to check through a script to find where you changed it. In order to allow for that all you need to do is assign either an ID or a class to the parent element of all your DIVs or add a CSS class to the DIV when you create it. Then you can define the floating in CSS and you don’t need to worry about it any longer. Be aware that you need to use the className property (d.className = ‘foo’) to assign a CSS class to an element and not setAttribute(‘class’,’foo’) as class is another reserved word.

Technorati Tags: netmag, netmaguk, webdevtrick, floating, css, javascript

Digg this | Add to deli.cio.us | Technorati
Chris @ / 5:09 pm filed under: General
Add a comment

Q&A: Internet Explorer keyboard navigation doesn’t work

Q: I have a Table of Contents at the beginning of a page that is linked to anchors around the headlines of all the content sections. When I click them with a mouse there is no problem – I get sent to the heading, read the paragraph and click the “back to top” link to go to the TOC. However, as I need to be accessible with this project I realised that when I use the keyboard and tab from link to link and hit enter I get sent to the section, but hitting tab doesn’t get me to the first link in this section but to the next item in the TOC! What am I doing wrong?

A: You are not doing anything wrong – Internet Explorer is (I assume this is what you are using). Internet Explorer has a really bizarre bug – it scrolls the page to a named anchor but fails to move the keyboard focus.

The fix for the problem has to do with IE’s hasLayout property. This property is set to true whenever an element has a defined height or width, is floated or has some other IE-only properties like zoom set. One solution to make IE move the keyboard focus is to contain the link in an element that has a hasLayout property of true, like a DIV with defined measurements.

This bug has been undiscovered for a long time as table cells by default have a hasLayout of true in IE and therefore the problem never occurred in table based layouts.

Another solution to the problem is to give the link a predefined tabindex property. If you don’t know how many links there are or you need tabindex for other reasons, you can use a tabindex of -1, which is not valid in HTML, but does the trick.

You can read more about this problem and the solutions in more detail over at Gez Lemon’s Juicy Studio :

Technorati Tags: netmag, webdevtrick, qanda, internet explorer, keyboard, accessibility

Digg this | Add to deli.cio.us | Technorati
Chris @ / 5:06 pm filed under: General
One comment

Getting ready for Singapore

I am right now burning 30 CDs (8/30 verifying right now) for my workshop on DOM scripting in Singapore in two days.

The flight is in 20 hours and will last 13 hours. I then have a day to recover until the 8 powerpoints with code examples and exercises for each will be shown to about 25 subscribers to the course. The really scary thing is that I have no idea what hotel I am in, but the organizer of the workshop promised to pick me up from the airport (that would be a first, I’ve never been picked up before!).

I will be back in London on Sunday morning and will leave again on Wednesday for the Highland Fling and will stay in Edinburgh until Sunday, most likely sharing a flat with Andy Budd.

Seeing that I normally only sleep 5-6 hours and write most of the time on the laptop, I really start to wonder why I pay for such a nice flat :)

Digg this | Add to deli.cio.us | Technorati
Chris @ 3/26/2007 / 7:53 pm filed under: General
One comment
Wait till I come is the blog of Christian Heilmann, a web developer living and working in London, England.
spacer spacer
gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.