简体   繁体   中英

preload asynchronously css images and sounds

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM