Slideshow
if (window.addEventListener){ window.addEventListener('load', slideShow, false); } else if (window.attachEvent){ window.attachEvent('onload', slideShow); } function slideShow() { /* GLOBALS **********************************************************************************************/ var globals = { slideDelay: 8000, // The time interval between consecutive slides. fadeDelay: 80, // The time interval between individual opacity changes. This should always be much smaller than slideDelay. wrapperID: "slideShowImages", // The ID of the <div> element that contains all of the <img> elements to be shown as a slide show. buttonID: "slideShowButton", // The ID of the <button> element that toggles the slide show on and off. buttonStartText: "Start Slides", // Text used in the slide show toggle button. buttonStopText: "Stop Slides", // Text used in the slide show toggle button. wrapperObject: null, // Will contain a reference to the <div> element that contains all of the <img> elements to be shown as a slide show. buttonObject: null, // If present, will contain a reference to the <button> element that toggles the slide show on and off. The initial assumption is that there is no such button element (hence the false value). slideImages: [], // Will contain all of the slide image objects. slideShowID: null, // A setInterval() ID value used to stop the slide show. slideShowRunning: true, // Used to record when the slide show is running and when it's not. The slide show is always initially running. slideIndex: 0, // The index of the current slide image. before: new Date(), //time interval checking now: new Date // against JS optimisations } /* MAIN *************************************************************************************************/ initializeGlobals(); if ( insufficientSlideShowMarkup() ) { return; // Insufficient slide show markup - exit now. } // Assert: there's at least one slide image. if (globals.slideImages.length == 1) { return; // The solo slide image is already being displayed - exit now. } // Assert: there's at least two slide images. initializeSlideShowMarkup(); //globals.wrapperObject.addEventListener('click', toggleSlideShow, false); // If the user clicks a slide show image, it toggles the slide show on and off. if (globals.buttonObject) { globals.buttonObject.addEventListener('click', toggleSlideShow, false); // This callback is used to toggle the slide show on and off. } //trying to circumvent FF JS unwanted behavior window.onfocus = startSlideShow; window.onblur = haltSlideShow; startSlideShow(); /* FUNCTIONS ********************************************************************************************/ function initializeGlobals() { globals.wrapperObject = (document.getElementById(globals.wrapperID) ? document.getElementById(globals.wrapperID) : null); globals.buttonObject = (document.getElementById(globals.buttonID) ? document.getElementById(globals.buttonID) : null); if (globals.wrapperObject) { globals.slideImages = (globals.wrapperObject.querySelectorAll('img') ? globals.wrapperObject.querySelectorAll('img') : []); } } // initializeGlobals // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function insufficientSlideShowMarkup() { if (!globals.wrapperObject) { // There is no wrapper element whose ID is globals.wrapperID - fatal error. if (globals.buttonObject) { globals.buttonObject.style.display = "none"; // Hide the not needed slide show button element when present. } return true; } if (!globals.slideImages.length) { // There needs to be at least one slide <img> element - fatal error. if (globals.wrapperObject) { globals.wrapperObject.style.display = "none"; // Hide the not needed <div> wrapper element. } if (globals.buttonObject) { globals.buttonObject.style.display = "none"; // Hide the not needed slide show button element. } return true; } return false; // The markup expected by this library seems to be present. } // insufficientSlideShowMarkup // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function initializeSlideShowMarkup() { var slideWidthMax = maxSlideWidth(); // Returns a value that is always in pixel units. var slideHeightMax = maxSlideHeight(); // Returns a value that is always in pixel units. globals.wrapperObject.style.position = "relative"; globals.wrapperObject.style.overflow = "hidden"; // This is just a safety thing. globals.wrapperObject.style.width = slideWidthMax + "px"; globals.wrapperObject.style.height = slideHeightMax + "px"; var slideCount = globals.slideImages.length; var rectImg; for (var i = 0; i < slideCount; i++) { globals.slideImages[i].style.opacity = 0; if (isIE()<=8) globals.slideImages[i].style.filter = 'alpha(opacity=0)'; //for IE globals.slideImages[i].style.position = "absolute"; rectImg = globals.slideImages[i].getBoundingClientRect(); globals.slideImages[i].style.top = (slideHeightMax - (rectImg.bottom-rectImg.top)) / 2 + "px"; globals.slideImages[i].style.left = (slideWidthMax - (rectImg.right-rectImg.left)) / 2 + "px"; } globals.slideImages[0].style.opacity = 1; // Make the first slide visible. if (isIE()<=8) globals.slideImages[0].style.filter = 'alpha(opacity=100)'; //for IE if (globals.buttonObject) { globals.buttonObject.textContent = globals.buttonStopText; } } // initializeSlideShowMarkup // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function maxSlideWidth() { var maxWidth = 0; var maxSlideIndex = 0; var slideCount = globals.slideImages.length; for (var i = 0; i < slideCount; i++) { if (globals.slideImages[i].width > maxWidth) { maxWidth = globals.slideImages[i].width; // The width of the widest slide so far. maxSlideIndex = i; // The slide with the widest width so far. } } var rect = globals.slideImages[maxSlideIndex].getBoundingClientRect(); return rect.right - rect.left; // Account for the image's border, padding, and margin values. Note that getBoundingClientRect() is always in units of pixels. } // maxSlideWidth // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function maxSlideHeight() { var maxHeight = 0; var maxSlideIndex = 0; var slideCount = globals.slideImages.length; for (var i = 0; i < slideCount; i++) { if (globals.slideImages[i].height > maxHeight) { maxHeight = globals.slideImages[i].height; // The height of the tallest slide so far. maxSlideIndex = i; // The slide with the tallest height so far. } } var rect = globals.slideImages[maxSlideIndex].getBoundingClientRect(); return rect.bottom - rect.top; // Account for the image's border, padding, and margin values. Note that getBoundingClientRect() is always in units of pixels. } // maxSlideHeight // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function startSlideShow() { globals.slideShowID = setInterval(transitionSlides, globals.slideDelay); } // startSlideShow // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function haltSlideShow() { clearInterval(globals.slideShowID); } // haltSlideShow // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function toggleSlideShow() { if (globals.slideShowRunning) { haltSlideShow(); if (globals.buttonObject) { globals.buttonObject.textContent = globals.buttonStartText; } } else { startSlideShow(); if (globals.buttonObject) { globals.buttonObject.textContent = globals.buttonStopText; } } globals.slideShowRunning = !(globals.slideShowRunning); } // toggleSlideShow // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function transitionSlides() { var currentSlide = globals.slideImages[globals.slideIndex]; globals.now = new Date(); var elapsedTime = (globals.now.getTime()-globals.before.getTime()); //console.log('Elapsed time: ' + elapsedTime); if (elapsedTime > globals.slideDelay) globals.slideIndex += Math.floor(elapsedTime/globals.slideDelay); else ++(globals.slideIndex); if (globals.slideIndex >= globals.slideImages.length) { globals.slideIndex = 0; } var nextSlide = globals.slideImages[globals.slideIndex]; var currentSlideOpacity = 1; // Fade the current slide out. var nextSlideOpacity = 0; // Fade the next slide in. var opacityLevelIncrement = 1 / globals.fadeDelay; globals.before = new Date(); var beforeFade = new Date; var nowFade = new Date; var fadeActiveSlidesID = setInterval(fadeActiveSlides, globals.fadeDelay); function fadeActiveSlides() { nowFade = new Date(); var elapsedFade = (nowFade.getTime()-beforeFade.getTime()); var multInc; if (elapsedFade > globals.fadeDelay) multInc= Math.floor(elapsedFade/globals.fadeDelay); else multInc = 1; currentSlideOpacity -= multInc*opacityLevelIncrement; nextSlideOpacity += multInc*opacityLevelIncrement; // console.log(currentSlideOpacity + nextSlideOpacity); // This should always be very close to 1. if (currentSlideOpacity >= 0 && nextSlideOpacity <= 1) { currentSlide.style.opacity = currentSlideOpacity; nextSlide.style.opacity = nextSlideOpacity; if (isIE() <= 8) { currentSlide.style.filter = 'alpha(opacity='+Math.floor(currentSlideOpacity*100)+')'; nextSlide.style.filter = 'alpha(opacity='+Math.floor(nextSlideOpacity*100)+')'; } } else { currentSlide.style.opacity = 0; nextSlide.style.opacity = 1; if (isIE() <= 8) { currentSlide.style.filter = 'alpha(opacity=0)'; nextSlide.style.filter = 'alpha(opacity=100)'; } clearInterval(fadeActiveSlidesID); } beforeFade = new Date(); } // fadeActiveSlides } // transitionSlides function isIE () { var myNav = navigator.userAgent.toLowerCase(); return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false; }//isIE } // slideShow