Povert

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

Archive for the ‘Tech & Science’ 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.

WordPress iPhone App

Friday, July 25th, 2008

Testing the wordpress iPhone app.

Twitter has ruined my ability to write more than a handful of words at a time.

Dynamic Resizing of Cross-Domain Iframes

Monday, May 19th, 2008

If you’ve ever wanted to have an iframe resize itself based on its (cross-domain) contents, you may have run into some problems.

I had to tackle this somewhat recently. The solution is silly, but it works.

The problem is that an iframe can’t communicate with its parent if they’re on different domains. For example, let’s say I put an iframe here on povert.com. The iframe could be pointing to, say, flappingcrane.com. Povert.com can’t access any useful information about the iframe, and vise-versa.

The solution is to have the iframed content (in this case flappingcrane.com) iframe something else from the original domain. So you could set up a file on povert.com called yaygo.html. Then flappingcrane.com iframes that, with a GET query. That GET query should contain any information you want to communicate to the parent (povert.com). Since yaygo.html is on povert.com, it can refer to povert.com with parent (though, since they’re different domains, it can’t do anything useful) and to flappingcrane.com with parent.parent. Because they’re on the same domain (even with the intermediate flappingcrane.com iframe), it can do something useful — like pass values from the GET query to a function:


parent.parent.setFunProps(iframeid, width, height, tacoflavor);

setFunProps() can then take those values and do what it wants with it (resize the iframe, whatever).

Another tidbit. If you give a name attribute to an iframe, that iframe’s contents can access the name with window.name. You can’t access window.id though, unfortunately. Either are handy for identifying to the parent document what iframe is requesting a resize, though there are other crappier ways to do it (passing its own url to match against iframe src, for example).

UPDATE: As I mention in my comment below, you can see an example of this at http://povert.com/fun/iframe/.

UPDATE (Oct 28, 2009): Looks like it doesn’t work in any version of IE now. It’s possible that Microsoft saw this as a security hole and fixed it.

Strudel, new Feed, S3

Wednesday, April 16th, 2008

“Toaster Strudel” is available at Flapping Crane’s music section. Good stuff. I use part of it for one of my ringtones.

Also, I’ve revamped the Flapping Crane RSS feed. This sucker now has MP4 videos that are good for watching on TV (with Apple TV or probably XBox 360) or on an iPhone. Haven’t tested it on other iPods. May not work on them.

Finally, I’m in the process of compressing new versions of all our old videos and uploading them to Amazon’s S3. This should allow for faster downloads.

I haven’t flipped the switch on S3 yet, and probably won’t for a while. I want to get as many vids on there as possible.

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