javascriptjqueryjquery-eventseaseljs

init() function undefined when using easeljs


I'm working on a small project to create an image gallery using easeljs and jQuery, I'm very new to both tools and this particular problem has got me scratching my head.

My HTML is very basic, I just want to get the functionality right before I start adding any bells and whistles :

<body onload="init();">
  <div style="margin-top:20px;" class="col-sm-8">
     <div class="embed-responsive embed-responsive-4by3">
        <canvas class="embed-responsive-item" id="slide-show" width="640" height="480"></canvas>
     </div>
  </div>
</body>

If I understand correctly, in order to set up a new stage and essentially get the whole script to work, I need to run an init() function at the start of my script.

$(document).ready(function(){
  //declare global variables
    var data;
    var stage;
    var canvas;
    var images = [];
    var bitmaps = [];
    var imageCount = 0;
    var slideshowInterval = 3000;

    //connect to feed.json
    $.ajax({
        url: 'json/feed.json',
        datatype: 'json',
        type: 'get',
        cache: false,
        success: function(data) {
          data = data;
        }
    });

    function init(){

      canvas = document.getElementById('slide-show');
      stage = new createjs.Stage(canvas);

      $(data.feed).each(function(index, value) {
          //populate the images array with content from feed.json
          images[index] = new Image();
          images[index].src = data.feed[index].source;
          images[index].onload = imageLoaded;
      });
    }

    function imageLoaded(){
      // go through all images and create bitmaps for them.
      imageCount++;
      if(imageCount >= images.length - 1){
        createBitmaps();
      }
    }

    function createBitmaps(){
      // create the bitmaps and add them to an array
      $(images).each(function(index, value){
        bitmaps[index] = new createjs.Bitmap(images[index]);
      });
    }

    function createSlider(){

      bitmaps.x = 0;
      bitmaps.y = 0;
      stage.addChild(bitmaps);

      setTimeout(slideshowInterval, slideImage(index));
    }

    function slideImage(index){

      // handle the animation of the slide effect and update dom with image details.
      $('#biscuit-name').html(data.feed[index].name);
      $('#biscuit-info').html(data.feed[index].text);
    }
});

Please also be aware this is certainly not finished and some of the functions are half done. I just wanted to do a bit of debugging as I worked on things and hit a wall at the first step with the init function seemingly not firing as intended.


Solution

  • The main problem is that <body onload="someFunction()"> will look for someFunction to be defined in the global scope, that is, it executes window.someFunction().

    Now, you init() is not at the global scope. It exists only inside the $(document).ready(function(){ ... }) function.

    So, one solution would be to add that init function to the global scope, like this:

    $(document).ready(function() {
         // ... all your current definitions
         window.init = init;
    });
    

    Pay attention here to the fact that init will only be defined and added to the window after the $(document).ready jQuery event is triggered. But it shouldn't be a problem, since $(document).ready normally fires earlier[1] than the onload event, thus defining init before it is called in <body onload="init()">.

    [1] $(document).ready is triggered after the HTML document has been loaded. onload is a built-in DOM event to be triggered after all content (including images and such) has been loaded.