Slideshow using PHP and JavaScript -


i have been trying create slideshow using php , javascript mainly. however, reason there no response after click >> or << move next or previous slide.

the php script used grab images folder , form them array. use javascript within php via echo transform php-array javascript-array.

i used this website tutorial.

thanks help!

<?php //php script: getimages.php //header("content-type: text/javascript");  //this function gets file names of images in current directory //and ouputs them javascript array function returnimages($dirname='c:\apache\htdocs\psych211lifespandevchpt1') {     echo "in return images";     $files = array();     $curimage = 0;      if ($handles = opendir($dirname)) {         echo "in handles";         while (false !== ($file = readdir($handles))) {             echo "in while";             $path_info = $_files['file']['name'];             $extensions = pathinfo($path_info, pathinfo_extension);             echo $extensions;             if ($extensions=='png')             //if(eregi($pattern, $file)) { //if file valid image                 //output javascript array element                 //$files->append($file);                 $files[$curimage] = $file;                 array_push($files,$file);                 //echo $files[$curimage];                 // 'slides['.$curimage.']="'.$file .'";';                 //echo $curimage;                 $curimage++;             //}         }         echo $curimage;         echo count($files);         closedir($handle);     }     echo '<html>     <head>     <script type="text/javascript">      var slides = [];     slides = '.json_encode($files).'; document.write(slides.length);     function cacheimage(imagesource) { // turns string image object         var imageobject = new image();         imageobject.src = imagesource;         return imageobject;     }      function showslide(direction) {        if (slideready) {           nextslide = currentslide + direction;           // disable buttons (ie-only)           document.slideshow.previous.disabled = (nextslide == 0);           document.slideshow.next.disabled = (nextslide ==      (slides.length-1));          if ((nextslide >= 0) && (nextslide < slides.length)) {                 document.images["screen"].src = slides[nextslide].src;                 currentslide = nextslide++;                 message = "picture " + (currentslide+1) + "of " +      slides.length;                 self.defaultstatus = message;                 if (direction == 1) cachenextslide();           }           return true;        }     }      function download() {        if (slides[nextslide].complete) {           slideready = true;           self.defaultstatus = message;        }        else settimeout("download()", 100); // checks download status every 100 ms        return true;     }      function cachenextslide() {        if ((nextslide < slides.length) && (typeof slides[nextslide] ==      "string"))     { // caches images once           slideready = false;           self.defaultstatus = "downloading next picture...";           slides[nextslide] = cacheimage(slides[nextslide]);           download();        }        return true;     }      function startslideshow() {        currentslide = -1;        slides[0] = cacheimage(slides[0]);        var slideready = true;        showslide(1);     }      </script>     </head>     <body onload="startslideshow()">  <form name="slideshow">  <table>  <tr>  <td colspan=2><img src="psych211lifespandevchpt1/slide-1.png" name="screen" width=108 height=135></td>  </tr>  <tr>  <td><input type="button" name="previous" value=" << " onclick="showslide(-1)"></td>  <td align="right"><input type="button" name="next" value=" >> " onclick="showslide(1)"></td>  </table>  </form>  </body>  </html>';  //return($files);       }      //echo 'var slides=new array();'; //define array in javascript     returnimages() //output array elements containing image file names     ?> 

most of functions use implicit global variable name slideready. in startslideshow use var slideready = true; try , set it. because prefaced var setting local variable named slideready, not global variable other functions have access to, global slideready remains undefined.

so when startslideshow calls showslide, line

if (slideready) { 

is interpreted as

if (false) { 

because global slideready undefined, falsy value. falsy value coerced false inside if statement, code inside of if block never runs , slide never changes.

using linter jshint or stricter jslint avoid these kinds of errors. running code in strict mode have made kind of error more apparent. there number of other implicit globals in code (nextslide, currentslide, message). implicit globals can cause errors or more insidious ones.

other things improved

window.self isn't commonly used. in particular way code uses bare self without prefacing window cause headaches. many people use variable named self store reference this in situations need access this object of outer function inside function using closure. using self refer window.self cause confusion reading code uses it. (it did me, has been long since have seen reference window.self forgot existed!)

window.defaultstatus has been obsolete long time, browsers don't have status bar anymore; no 1 see messages being posted there.

this code has lot of variable names capitalized. valid code , run, in javascript has become convention constructor functions capitalized. in simplest of terms, constructor function function needs called new keyword. if in future (including you) works on code, function name being capitalized reminder need use new keyword before it. linters use convention automatically spot missing news you.

accessing form elements via document.formname.elementname , images via document.images outdated techniques. using document.formname.elementname can cause problems if form element has same name property of form. instead giving each button idand accessing via document.getelementbyid. in fact, don't need use form , buttons, easy style div or span element button.

using onclick dated way of attaching events, embedding in onclick in html. less obtrusive use addeventlistener instead.

for number of reasons many people writing modern javascript prefer use function expressions define functions instead of function declaration. function declarations can cause puzzling bugs, whereas function expression stored in variable behaves more predictably.

global variables bad , can lead sorts of weird bugs, different parts of code need access common variables. can allow without creating globals wrapping code in immediately-invoked function expression (iife) (sometimes called self-invoking function).

(function () {   'use strict';   var shared = true,     foo = function () {       // has access shared     },     bar = function () {       // has access shared     }; // can access shared here }()); // can't access shared here because not global 

i don't feel necessary or worth preload images. people have reasonably fast connection , if images encoded load in progressively , viewable in state quicker code won't display image until loaded. loading next image before user requests wastes bandwidth important if on mobile.

if think preloading images important, instead of using overly complex system won't display next picture until downloaded, preload them @ beginning:

slides.foreach(function (url) {   (new image()).src = url; }); 

this download each image , store in browsers cache instead of keeping in memory in array code posted does.

modernizing code

a more modern version of javascript code tutorial might more this:

<img id="slide"></td> <div class="slide-controls">   <span class="button" id="prev-slide">&laquo;</span>   <span class="button" id="next-slide">&raquo;</span> </div>  <script>   (function () {     'use strict';     var slides = [         'http://www.placecage.com/300/200',         'http://www.placecage.com/g/300/200',         'http://www.placecage.com/c/300/200',         'http://www.placecage.com/gif/300/200'       ],       currentslide = 0,       doc = document,       elslide = doc.getelementbyid('slide'),       elprev = doc.getelementbyid('prev-slide'),       elnext = doc.getelementbyid('next-slide'),        showslide = function (index) {         if (index > -1 && index < slides.length) {           currentslide = index;           elprev.classlist.remove('disabled');           elnext.classlist.remove('disabled');           if (index === 0) {             elprev.classlist.add('disabled');           } else if (index === slides.length - 1) {             elnext.classlist.add('disabled');           }           elslide.src = slides[index];           elslide.title = 'picture ' + (index + 1) + 'of ' + slides.length;         }       },       changeslide = function (step) {           var index = currentslide + step;           showslide(index);       },       prevslide = changeslide.bind(null, -1),       nextslide = changeslide.bind(null, 1);      elprev.addeventlistener('click', prevslide, false);     elnext.addeventlistener('click', nextslide, false);      showslide(0);   }()); </script> 

jsfiddle

there no need use docuemnt load event (aka onload), elements defined in markup above javascript code , available when javascript code runs.

instead of using defaultstatus, putting status message in title attribute on image, should show tool-tip in browsers if user mouses-over image. output message <div> if want visible without mouse-over.

i used function.prototype.bind create event hanlders prevslide , nextslide.

the lines

  prevslide = changeslide.bind(null, -1),   nextslide = changeslide.bind(null, 1); 

are equal to

  prevslide = function () {     changeslide(-1);   },   nextslide = function () {     changeslide(1);   }; 

since separated changeslide logic actual display of image , showslide takes index instead of how many forward or go, easy make function jumps first or last slide too:

  var firstslide = showslide.bind(null, 0),     lastslide = showslide.bind(null, slides.length - 1); 

jsfiddle

other resources

here few resources related techniques used.