0

All of the assets of the site are in an array of objects that will be shown after user interaction, something like a slider.

{"id":"1","icon":"icon-name-class","sound":"soud-name"},
{"id":"2","icon":"icon-2-name-class","sound":"soud-2-name"},
....
{"id":"100","icon":"icon-100-name-class","sound":"soud-100-name"}

I have about 150 small icons and around 100 small sounds that need to be preloaded, been looking and didn't find anything related to preload assets from a js array.

I'm using the images as a background and getting the class name from the object. I thought that all images would be ready since they are coming from a css class, but i guess that i am wrong

.icon-class-1 { background-image: url(../img/icons/img-1.png); }

this link or something similar to this could do the trick but after reading the doc couldn't find how to apply it when the assets origin is in an array that will be managed with js.

Tyra Pululi
  • 436
  • 1
  • 7
  • 19

1 Answers1

1

You have to loop through the object array to load them.

EDIT

Since you have a lot images which doesn't load via CSS.
I suggest you remove all these backgroung-image:url('...'); and put these URLs in your json like this:

{"id":"1","icon":"icon-name-class", "icon_url":"http://domain/path/file.jpg", "sound":"sound-name","sound_url":"http://domain/path/file.mp3"},

And do the same for your sound urls.
PLUS! It will ease the maintenance in the long run... If you notice a broken URL someday.
Then, preloading can be made like this:

var object_array = [
  {"id":"1","icon":"icon-name-class", "icon_url":"http://domain/path/file1.jpg", "sound":"sound-name","sound_url":"http://domain/path/file1.mp3"},
  {"id":"2","icon":"icon-name-class", "icon_url":"http://domain/path/file2.jpg", "sound":"sound-name","sound_url":"http://domain/path/file2.mp3"},
  {"id":"3","icon":"icon-name-class", "icon_url":"http://domain/path/file3.jpg", "sound":"sound-name","sound_url":"http://domain/path/file3.mp3"}
];

// Preloading arrays
var icon_url_arr = [];
var sound_url_arr = [];

// Load counter
var loaded_counter={icon:0,sound:0};
function increment_counter(x){
  loaded_counter[x]++;
}

// Loop through the data array
for(i=0;i<object_array.length;i++){
  if(typeof(object_array[i].icon_url)!="undefined"){
    icon_url_arr[i] = $("<img>").attr("src",object_array[i].icon_url).on("load",function(){increment_counter("icon");});
  }

  if(typeof(object_array[i].sound_url)!="undefined"){
    var audio_element = $("<audio>").attr("id","audio_"+i);
    sound_url_arr[i] = $("<source>").attr("src",object_array[i].sound_url).attr("type","audio/mpeg");
    audio_element.append(sound_url_arr[i]).on("loadeddata",increment_counter("sound"));
    $("#main").append(audio_element);
  }
}

// Interval to check load status
var check_all_loaded = setInterval(function(){
  console.log("Loded icons: " +loaded_counter.icon+ " Loaded sounds: " +loaded_counter.sound );
  $("#icon").html((loaded_counter.icon/icon_url_arr.length)*100+"%");
  $("#sound").html((loaded_counter.sound/sound_url_arr.length)*100+"%");

  // Stop the interval when all loaded
  if( (icon_url_arr.length==loaded_counter.icon) && (sound_url_arr.length==loaded_counter.sound) ){
    clearInterval(check_all_loaded);
    console.log("Load check Interval stopped.");

    // Now you can use the loaded icons and sounds
    cycle_data();
  }
},10);

// cycle through data on interval
function cycle_data(){
  console.log("Display Interval started.");

  // Background
  var i=0;
  setInterval(function(){

    $("#main").css("background-image","url("+icon_url_arr[i].attr("src")+")");

    // Audio
    $(document).find("audio").get(0).pause();
    $(document).find("#audio_"+i).get(0).play();

    // Increment loop counter.
    i++;

    // Reset counter when the array end is reached
    if(i==icon_url_arr.length){
      i=0;
    }
  },2000);
}

So it won't be displayed or played anywhere...
But the browser will have it loaded.

You may have to hide the audio players via CSS:

audio{
  display:none;
}

I made a CodePen demo to make sure it is working.
There is only 3 items in json...
And images and sounds are pretty small.
So you won't really notice the load delay in this demo. ;)

I suggest you place this script in a document.ready() wrapper...
And within a setTimeout() function to execute it something like 0.5 to 2 seconds after document is ready.
So the rest of your page won't lag.

Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64
  • Thanks for pointing me in the right direction, I edited the op with more details about the way i am using the images. The only thing that i haven't clear is how to detect when all assets are downloaded in order to remove the preloading screen. – Tyra Pululi May 28 '17 at 06:19
  • I made you something cool... This should be your solution. ;) – Louys Patrice Bessette May 28 '17 at 16:45
  • finishing adapting your code, icons are loading as expected but i am getting a status 206 partial content with the sounds. any idea why is this happening? – Tyra Pululi May 30 '17 at 16:27
  • That is normal and desirable. It mean the file is "partialy" preloaded. There is enough downloaded to start the audio. And on play, it will resume downloading. ;) – Louys Patrice Bessette May 30 '17 at 16:54
  • 1
    great thanks, everything is working excepting the check_all_loaded, it is closing the preloader screen before the download is complet, i can see the console message pretty early – Tyra Pululi May 30 '17 at 17:28
  • mmm... I don't see what can cause this. Do you have a live link to share so I could actually see it with more files ? – Louys Patrice Bessette May 30 '17 at 17:33
  • No i dont, and I understand that without looking a it there is nothing you can do. i am consoling loaded_counter within increment_counter function and all the 180 objects in the array are shown practically as the page is ready not taking into consideration if the files load was initiated. – Tyra Pululi May 31 '17 at 05:37
  • Look at the "Network" tab in the dev tools [F12] after a cache flush. ;) – Louys Patrice Bessette May 31 '17 at 05:42
  • Been doing it all the time,, I think it is happening in your demo too, console and preload info are showing 100% before assets download beggins – Tyra Pululi May 31 '17 at 06:08
  • 1
    just fixed :) .on("load", function () { increment_counter("icon"); }); Thanks man, really helped – Tyra Pululi May 31 '17 at 10:23
  • Absolutely no idea. I don't have any Apple device to test. I know some display positionning issues... But about sound, no. – Louys Patrice Bessette Jun 01 '17 at 14:07