Povert

Words About Things

Archive for the ‘WWW’ 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.

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/.

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.

Worst HTML/CSS/JS

Friday, November 9th, 2007

I’ve been working on what I believe may be some of the worst and most offensive (but still “working”) use of HTML, CSS and Javascript possible. You know, for fun.

Here’s what I’ve got so far (line breaks added for *cough* legibility):


<SCRIPT LANGUAGE=JSCRIPT>
eval("document.write('<!--[IF LT IE 9]>
<STYLE>*LI#BLUENAV{
_ZOOM:1!IMPORTANT*BACKGROUND-COLOR:
PAPAYAWHIP!IMPORTANT<![ENDIF]–></STYLE>
<BASEFONT SIZE=30 COLOR=YELLOWGREEN FACE=GEORGIA>
<TABLE CELLPADDING=10 CELLSPACING=10 BORDER=20>
<TD><U><TABLE><S><LI ID=BLUENAV>
<FONT FACE=VERDANA STYLE=FONT-SIZE:LARGE>
<B><CENTER><MARQUEE BGCOLOR=MISTYROSE WIDTH=50%>
Tacos</MARQUEE><BR>
<IMG ALIGN=LEFT SRC=SPACER.GIF WIDTH=200 HEIGHT=20>’)”)
</SCRIPT><NOSCRIPT><A HREF=HTTP://MICROSOFT.COM>
<FONT FACE=COURIER COLOR=SADDLEBROWN>
YOU&NBSP;NEED&NBSP;INTERNET&NBSP;EXPLORER&NBSP;TO&NBSP;
EXPERIENCE&NBSP;THIS&NBSP;WEB&NBSP;SITE&NBSP;
AS&NBSP;INTENDED

To see it in action, click here. You’ll need IE, of course. It wouldn’t be as crappy otherwise.

Key points:

  • <script> has a LANGUAGE attribute. And it’s JSCRIPT, for fun.
  • Elements are closed only when absolutely necessary
  • No quotes around element attributes
  • Nearly everything in uppercase
  • eval()
  • document.write()
  • Needlessly nested (and otherwise unnecessary) tables
  • Not a <tr> to be found.
  • Insane colors: PapayaWhip, MistyRose, YellowGreen and SaddleBrown
  • <basefont> and <font>
  • <li> without a <ul> or <ol>
  • <noscript> — some people may argue with me about this one, but it’s certainly not an indicator of whether the viewer is using IE
  • Pointless use of &nbsp;
  • <marquee>
  • <u>, <s>, <b> and <center>
  • IE conditional comments (useful, but crappy nonetheless)
  • * and _ CSS hacks
  • !important
  • Improperly formatted (but working) css
  • Opening <style> tag inside conditional comment, closing tag outside.
  • No DOCTYPE
  • No attempt at an even reasonably structured HTML document — no <html>, no <head>, no <body>, etc.
  • Oh, and SPACER.GIF doesn’t exist, of course. That’s a double-whammy, actually. Spacer images blow.

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