Slideshow Javascript Code


/// Set Namespace
/// ...
var PreytellNS = {};

// ===========================================================
// SlideShow object ~
// ===========================================================

PreytellNS.slideShow = function(slideSpeed, imageDiv, titleDiv)
{
    // ===================================================
    // private member variables ~
    // ===================================================

    var imageItems   = new Array();             // array for storing images
    var imageXHtml   = "<img src=\"{0}\"/>";    // image tag used in the slideshow
    var imageIndex   = -1;                      // current slide index
    var transSteps   = 20;                      // percentage-delta for image-transition
    var transSpeed   = 40;                      // interval between opacity-transitions
    var transTimer;                             // timer for image-transition-iterations
    var imageTimer;                             // timer for image-iterations

    // ===================================================
    // slideShow utility objects ~
    // ===================================================

    // image-item object... closure example...
    // ...
    function imageItem(src, title) {

        this.src = src;
        this.title = title;
    }

    // add prototype for image preloader method...
    // ...
    imageItem.prototype.loadImage = function(img) {

        img.src = this.src;
    }

    // ===================================================
    // slideShow private methods ~
    // ===================================================

    // addItem method...
    // ...
    var addItem = function(src, title) {

        imageItems.push(new imageItem(src, title));
    }

    // renderImage method...
    // ...
    var renderImage = function(opacity, direction) {

        transTimer = clearTimeout(transTimer);

        opacity = opacity + (transSteps * direction);
        opacity = (opacity < transSteps ? 0 : (opacity > 100 - transSteps ? 100 : opacity));
 
        if(opacity < 100) {

	        if (opacity < transSteps) {

		        var imgItem = imageItems[imageIndex];
		        var inrHtml = imageXHtml.replace("{0}", imgItem.src);
		        imageDiv.innerHTML = inrHtml;
		        titleDiv.innerHTML = imgItem.title; /// String(imageIndex + 1) + ") " + imgItem.title;
		        direction = 1;
	        }

        }

        // set the target image's style.opacity...
        setOpacity(opacity);
		
        // create timer-function for timed, recursive call...
        var _renderImage = function() {

	        renderImage(opacity, direction); 
	        _renderImage = null; // garbage collection.
        }

        // call timer-function to change image opacity...
        transTimer = setTimeout(_renderImage, transSpeed);
    }

    // setOpacity method...
    // ...
    var setOpacity = function(opacity) {

        // set the target image's style.opacity...
        var imgs = imageDiv.getElementsByTagName("img");

        if (imgs.length) {
	        try {
		        if (window.isIE)
			        imgs[0].style.filter = "alpha(opacity=" + opacity + ")";
		        else 
			        imgs[0].style.opacity = opacity/100;
	        } catch(e) {}
        }
    }

    // renderImages method - begin rendering images...
    // ...
    var renderImages = function(increment) {

        imageTimer = clearTimeout(imageTimer);

        var uBound = imageItems.length - 1;
        imageIndex = imageIndex + (increment ? increment : 1);
        imageIndex = imageIndex < 0 ? uBound : (imageIndex > uBound ? 0 : imageIndex);
 
        renderImage(100, -1);

        // create timer-function for timed, recursive call...
        var _renderImages = function() {

	        renderImages(1); 
	        _renderImages = null; // garbage collection.
        }

        // call timer-function to load adjacent image...
        imageTimer = setTimeout(_renderImages, slideSpeed);
    }

    // parseXmlToArray method...
    // ...
    var parseXmlToArray = function(xmlHttp) {

        var xmlDoc = xmlHttp.responseXML.documentElement;
        var xmlNodeEntries = xmlDoc.getElementsByTagName('entry');

        // populate the slideshow images array...
        if (xmlNodeEntries.length) {

	        for (var i=0; i < xmlNodeEntries.length; i++) {

		        var xmlNodeLinks = xmlNodeEntries[i].getElementsByTagName('link');
		        if (xmlNodeLinks.length) {

			        var xmlTargetNode = xmlNodeLinks[1];
			        var xmlAttribute = xmlTargetNode.attributes.getNamedItem('href');
			        var imageSrc = xmlAttribute.value;
			        var xmlNodeTitles = xmlNodeEntries[i].getElementsByTagName('title');
			        var imageTitle = xmlNodeTitles[0].childNodes[0].nodeValue;

			        // add a new image to the array...
			        addItem(imageSrc, imageTitle);
		        }
	        }
        }
    }

    // ===================================================
    // slideShow public methods ~
    // ===================================================

    // moveToPrevious method...
    // ...
    this.moveToPrevious = function() {

        imageTimer = clearTimeout(imageTimer);
        renderImages(-1);
        return true;
    }

    // pauseModule method...
    // ...
    this.pauseModule = function() {

        if (imageTimer)
	        imageTimer = clearTimeout(imageTimer);
        else
	        renderImages(1);
        return (imageTimer ? 0 : 1);
    }

    // moveToNext method...
    // ...
    this.moveToNext = function() {

        imageTimer = clearTimeout(imageTimer);
        renderImages(1);
        return true;
    }

    // initModule method...
    // ... 
    this.initModule = function(url) {

        var client = new PreytellNS.xmlHttpClient();
        client.async = true;
        client.onerror = handleError;
        client.callback = parseResponseXml;

        try {
	        client.makeRequest(url, null);
        } catch(e) {
	        throw(e);
        }

        function handleError(msg) {
	        throw(new Error(msg));
        }

        function parseResponseXml() {

	        // parse the response xml to load-up the image array... 
	        parseXmlToArray(client.xmlHttp);

	        // if images exist, begin slideshow ...
	        if (imageItems.length > 0) {

		        // put up a ui wait message...
		        titleDiv.innerHTML = "loading slideshow images. please wait...";

		        // get images to preload after the first one is loaded...
		        var img = new Image();

		        // create timer-function for timed call to preload images...
		        var _preloadImages = function() {

			        for(i=1; i < imageItems.length; i++)
				        imageItems[i].loadImage(new Image());

			        img.onload = _preloadImages = null; // garbage collection.
		        }

		        // call timer-function  to preload remaining images 
		        // whwn as the first image's onload event fires...
		        img.onload = function() {

			        setTimeout(_preloadImages, slideSpeed/2);
		        }

		        // preload the first image...
		        imageItems[0].loadImage(img);

		        // create timer-function to allow time for first image to fully-load...
		        var _renderImages = function() {

			        renderImages(0); 
			        _renderImages = null; // garbage collection.
		        }

		        // use timer-function to begin slideshow after short interval...
		        imageTimer = setTimeout(_renderImages, 2000);
	        }

	        client.xmlHttp = null; // garbage collection.
        }
    }
}

// ===========================================================
// xmlHttpClient wrapper ~
// ===========================================================

PreytellNS.xmlHttpClient = function()
{
    this.xmlHttp;
    this.async;  
    this.method = "GET"; 
    this.callback;
    this.onerror = function(msg) {};

    this.init = function() {

        if (typeof XMLHttpRequest != 'undefined') {
	        this.xmlHttp = new XMLHttpRequest();
        } else if (window.ActiveXObject) {

	        var aVers = ["MSXML2.XmlHttp.3.0", "MSXML2.XmlHttp", "Microsoft.XmlHttp"];
	        var xmlHttpObj;
	        for (var i = 0; i < aVers.length-1; i++) {
		        try {
			        xmlHttpObj = new ActiveXObject(aVers[i]);
		        } 
		        catch(e) {}
	        }
	        this.xmlHttp = xmlHttpObj;
        }
    };
    this.makeRequest = function(url, data) {

        var self = this;
        if (!this.xmlHttp) this.init();

        if (this.xmlHttp) {
	        this.xmlHttp.open(this.method, url, this.async);
	        this.xmlHttp.onreadystatechange = function() {
		        self.onReadyStateChange();
	        }
	        this.xmlHttp.send(data);
	        return this.xmlHttp;

        } else {
	        this.onerror("cannot create XMLHttpRequest object");
        }
    };
    this.validateResponse = function(xmlHttp) {
        var conType = String(xmlHttp.getResponseHeader("Content-Type"));
        var isXmlDoc = (conType == "text/xml");

        // handle atom/xml feed for IE by calling loadXML...
        if (!isXmlDoc && conType.indexOf("application/atom") > -1) {

	        if (window.ActiveXObject) {
		        // remove processing instruction...
		        var regEx = new RegExp("<\?.*\?>"); 
		        var responseText = (xmlHttp.responseText).replace(regEx, "");
		        xmlHttp.responseXML.loadXML(responseText);
	        }
	        isXmlDoc = true;
        }
        return isXmlDoc;
    };
    this.onReadyStateChange = function() {
        if (this.xmlHttp.readyState == 4) {
	        if (this.xmlHttp.status == 200) {
		        if (this.validateResponse(this.xmlHttp))
			        this.callback();
		        else
			        this.onerror("cannot validate XMLHttp response");
	        } else {
		        this.onerror("cannot fetch XMLHttp response");
	        }
        }
    }
}