Povert

It's Pronounced "Pah-vert." You povert.

Archive for the ‘Javascript’ Category

CSS-centric JS

Thursday, September 11th, 2008

This probably isn’t news to anyone deep in JS/CSS land, but I thought these notes may be handy for someone who’s still figuring out the best way to approach some problems.

There’s a temptation, I think, to go overboard with JS when manipulating elements on a page. Many tasks can be more simply handled with a combination of JS and CSS.

For example, let’s say you have a simple unordered list:

<ul id="happyList">
  <li><a href="tacos.html">Tacos</a></li>
  <li><a href="burritos.html">Burritos</a></li>
  <li><a href="enchiladas.html">Enchiladas</a></li>
  <li><a href="tamales.html">Tamales</a></li>
  <li><a href="chalupas.html">Chalupas</a></li>
  <li><a href="antacids.html">Antacids</a></li>
</ul>

Let’s say that you only want 3 items to show by default, and you want a “More” link at the bottom that will expand the list to show the rest.

There’s a few ways you could approach this. People may be tempted to put an onclick event onto the “More” link, then have that call a function that toggles the visibility of each element after the third. Something like:


var happy = document.getElementById('happyList');
var items = happy.getElementsByTagName('li');
function showLinks() {
  for (var i=3; i < items; i++) {
    items[i].style.display = 'list-item';
  }
}
function hideLinks() {
  for (var i=3; i < items; i++) {
    items[i].style.display = 'none';
  }
}

That would work (though I haven’t actually tested this particular js), but it’s definitely the crappy way, for a number of reasons. First, there’s no need for two functions, though that’s beside the point of this post. Second, we’re running through a for() loop every time each function is called.

Instead of something like that, the way I’d do it is to first set up this CSS:


#happyList.collapsed li {
  display: none;
}
#happyList.collapsed li.alwaysShow {
  display: list-item;
}

Then, you put a class of ‘alwaysShow’ on the first three list item elements, either in the html itself or with javascript:


function assignShow() {
  var happy = document.getElementById('happyList');
  var items = happy.getElementsByTagName('li');
  for (var i=0; i < items.length && i < 3; i++) {
    items[i].className = 'alwaysShow';
  }
}

Now, when the ul has a class of ‘collapsed’, only the first three items show:


function toggleList() {
  var happy = document.getElementById('happyList');
  if (happy.className == 'collapsed') {
    happy.className = '';
  } else {
    happy.className = 'collapsed';
  }
}

Or, more succinctly:

function toggleList() {
  var happy = document.getElementById('happyList');
  happy.className = happy.className ==
    'collapsed' ? '' : 'collapsed';
}

Then, either in HTML or using javascript, you can add an element with the “More” text and attach an event to it that calls toggleList().

I’m being a little vague on details here. My main point is that it’s preferable to lean on CSS as much as possible. It helps to avoid micromanaging elements.

Povert is proudly powered by WordPress
Entries (RSS) and Comments (RSS).