Home > CSS | DOM | JavaScript > Javascript controls on filmstrip

Javascript controls on filmstrip

In this article we’re going to look at how to add some direction controls to our filmstrip. At the end of the last article we had the following filmstrip:

Horizontal scrollbars in <div> tags don’t really play that nicely with scroll wheels or key controls unless you set the tabindex property. I’ve done so on the filmstrip above, and given it tabindex="1" so it’s the first thing you tab to. Just press left or right to test it out. And, although the scrollbars work well enough, let’s try something different. There are several ways to accomplish this, but some are distinctly better than others. I say better because of how well, or poorly, they play with browsers.

The method I describe below is doing nothing more than changing the display css-attribute. It also uses a couple of different ways to move the filmstrip images.

First let’s look at the events. Using the following for your onload function:

function onLoad() {
	if (document.addEventListener) {
		document.getElementById('strip').addEventListener('keypress',HandleKeyPress,false);
		document.getElementById('strip').addEventListener('DOMMouseScroll',HandleWheel,false);
		document.getElementById('larrow').addEventListener('click',moveLeft,false);
		document.getElementById('rarrow').addEventListener('click',moveRight,false);
	} else {
		document.getElementById('strip').onkeypress = HandleKeyPress;
		document.getElementById('strip').onmousewheel = HandleWheel;
		document.getElementById('larrow').onclick = moveLeft;
		document.getElementById('rarrow').onclick = moveRight;
	}
	thumbNum = document.getElementById("imagerow").getElementsByTagName("li").length;
	setLeft();
}

The only reason for the difference is that some browsers don’t support the addEventListener method. setLeft() we’ll see a little bit later on. thumbNum is just a convenient store for the number of thumbnails.

Next let’s look at some of the variables we’re using and how they’re initialized:

var thumbNum;    //total number of thumbnails
var showNum = 4; //how many thumbnails to show
var curLeft = 0; //current index of the leftmost thumbnail

thumbNum we already know gets initialized in the onLoad function. showNum and curLeft are used throughout the script.

Next, let’s look at the events and what they call:

function HandleKeyPress(e) {
	switch (e.keyCode) {
		case e.DOM_VK_LEFT:
			moveLeft();
			break;
		case e.DOM_VK_RIGHT:
			moveRight();
			break;
		case e.DOM_VK_ESCAPE:
			content.focus();
			return;
	}
}

/** Event handler for mouse wheel event.
 * originally from http://adomas.org/javascript-mouse-wheel/
 */
 function handle(delta) {
        if (delta < 0)
		moveRight();
        else
		moveLeft();
}

function HandleWheel(event){
        var delta = 0;
        if (!event) /* For IE. */
                event = window.event;
        if (event.wheelDelta) { /* IE/Opera. */
                delta = event.wheelDelta/120;
                /** In Opera 9, delta differs in sign as compared to IE.
                 */
                if (window.opera)
                        delta = -delta;
        } else if (event.detail) { /** Mozilla case. */
                /** In Mozilla, sign of delta is different than in IE.
                 * Also, delta is multiple of 3.
                 */
                delta = -event.detail/3;
        }
        /** If delta is nonzero, handle it.
         * Basically, delta is now positive if wheel was scrolled up,
         * and negative, if wheel was scrolled down.
         */
        if (delta)
                handle(delta);
        /** Prevent default actions caused by mouse wheel.
         * That might be ugly, but we handle scrolls somehow
         * anyway, so don't bother here..
         */
        if (event.preventDefault)
                event.preventDefault();
	event.returnValue = false;
}

Looking at HandleKeyPress we see that it does a short switch-case on the keycode from the event. You can use this same technique to add other keypress events. There are also keyup and keydown events which have their uses.  The best list of the keycodes available is here.

The mouse wheel event I’ve borrowed from another site (no point in re-inventing the wheel). The annoying part about the mouse wheel is that every browser interprets the event differently. Sooo… the script has to check for them all.

Both, the mouse wheel event and the keypress event, call moveLeft() and moveRight(), which are shown below:

function moveLeft(){
  if (curLeft == 0) return; //already at the left
  else {
    curLeft = curLeft - 1;
    setLeft();
  }
}

function moveRight() {
  if (curLeft==thumbNum-showNum) return; //already at the right
  else {
    curLeft = curLeft + 1;
    setLeft();
  }
}

All these do is check to see if they’re already at the left or the right and then increase or decrease curLeft and call setLeft(). setLeft is what does our styling changes.

function setLeft(){
	var rng = getRanges();
	for (var i = 0; i < rng.out.length; i++ ) {
		rng.out[i].setAttribute("style","display:none;");
		rng.out[i].style.display = "none";
	}
	for (var i = 0; i< rng.in.length; i++ ) {
		rng.in[i].setAttribute("style","display:inline;");
		rng.in[i].style.display = "inline";
	}
}

The first thing it does is get the ranges of elements which will be hidden or shown. Then it loops through those outside the range to be shown and hides them. Finally it loops through those inside the range to be shown and displays them.

function getRanges() {
	var end = curLeft + showNum - 1; //calculate the image position at the end of the display

	var iva = new Array();	//create arrays for the in and out of range elements
	var ova = new Array();

	//get all of the <li> tags inside our imagrow
	var litags = document.getElementById("imagerow").getElementsByTagName("li");

	// loop through and add them to iva or ova if they
	// are in or out, respectively, of our desired range
	for (var i = 0; i < litags.length; i++) {
		if ((i < curLeft) || (i > end))
			ova.push(litags[i]);
		else
			iva.push(litags[i]);
	}
	return { in: iva, out: ova };
}

It’s pretty well commented but just to make some things clear: The childNodes and getElementsByTagName collections don’t work exactly like arrays and specifically they don’t support slice(). Therefore, we just make two new arrays and sort through the collection items. The finished product looks like ths:

Go ahead and try some of the events out. The key events only work if the strip has focus, so either click on it, or tab to it first.

If you want to see what it looks like on it’s own, here’s the html, the javascript, and the css

Comments:1

Leave a Reply
  1. Reply paul
    11/03/08

    very very very tan q sir! it is very useful.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackbacks:0

Listed below are links to weblogs that reference
Javascript controls on filmstrip from Ashita.org
TOP