Teaching myself javascript

My web design skills are a little on the old side. Probably frozen around 1997; Netscape Navigator 2 would probably render most of my stuff properly.

As part of the “make work” project I did last month I wanted to try something new. With the existing version if you clicked on a link to get cover-art then it would just be a simple link. You see the image then press “BACK”. This worked well for years, but some mobile devices don’t cache too well. And even if they do then the rendering time can be quite large. One obvious option would be to open in a new window (tab, whatever), but I thought I’d try to do “popups”. It turns out the term of art is “lightbox”.

Armed with that I found Lightbox 2. It took 5 minutes to integrate that into my page. And it worked. Trouble is that it required jQuery so the whole thing took over 100K. Considering the original page was less than 80K, I’ve over doubled my download size.

Also I didn’t learn anything from this. So a solution that worked, but was unsatisfying.

I did some more searching around. I found some “10 line” solutions, which looked fun… but they all worked on the concept of setting the image to be invisible and then show it on demand. Which, given I was planning on 1200 images, would have meant pre-loading all 1200 images on the page in the off-chance of clicking on one or two links.

But I did learn from these things.

My goal was to have 1 image; change what the image displayed; move it to the right place; then display it.

It turns out to be a simple concept, but slightly messy.

The core code is a small CSS:

  <style>
    .white_content {
      display: none;
      position: absolute;
      padding: 16px;
      background-color:#eae9d4;
      z-index:1000;
      overflow: auto;
    }
  </style>

And then some javascript

<script type="text/javascript">
var oldfocus = null;

function set_img(i,e)
{
  document.images['popup'].src=i;
  oldfocus=e;
  var x=e.offsetLeft+e.offsetParent.offsetLeft-20;
  var y=e.offsetTop+e.offsetParent.offsetTop-200;
  if (x<0) { x=0; }
  if (y<0) { y=0; }
  document.getElementById('light').style.left=x + 'px';
  document.getElementById('light').style.top=y + 'px';
  document.getElementById('light').style.display='block';
  document.getElementById('poplink').focus();
  return false;
}
function hide()
{
  document.getElementById('light').style.display='none';
  oldfocus.focus();
}
</script>

Add in a DIV to hold the image:

<div id="light" class="white_content">
<a id='poplink' href='javascript:void(0)' onclick="hide()"><img border=0 name=popup src="images/spacer.gif"></a>
</div>

And now it’s easy to call:

<a target=_blank href="images/sp-sweh.gif" onClick="return set_img('images/sp-sweh.gif',this)">South Park</a>

Originally I wrote the code to track X,Y position by catching mousedown events. But keyboard navigation (eg TABbing to a link and pressing RETURN) doesn’t cause mousedown events, so no X,Y is captured. So this code tries to work out where the link is on the page and use that. It turns out the “offsetParent” stuff should really be chained; eg a link inside a table has the link offset relative to the cell; the cell offset relative to the table; the table offset relative to the page. So that code got rewritten as a loop in my final version. But, basically, that’s a lightbox with 33 lines of code.

Next I wanted to see if I could render HTML rather than show images. Turns out it’s mostly the same thing; Using the “innterHTML” attribute allows a DIV to render almost anything, not just images.

The final solution…Image popups and HTML popups