javascript - 异步预加载 css 图像和声音

标签 javascript jquery css preloadjs

网站的所有 Assets 都在一组对象中,这些对象将在用户交互后显示,类似于 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"}

我有大约 150 个小图标和大约 100 个小声音需要预加载,一直在寻找并没有找到与从 js 数组预加载 Assets 相关的任何内容。

我将图像用作背景并从对象中获取类名。 我认为所有图像都已准备就绪,因为它们来自 css 类,但我想我错了

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

this link或类似的东西可以解决问题,但在阅读文档后找不到如何在 Assets 来源位于将使用 js 管理的数组中时应用它。

最佳答案

您必须遍历对象数组才能加载它们。

编辑

因为您有很多图片无法通过 CSS 加载。
我建议您删除所有这些 backgroung-image:url('...'); 并将这些 URL 放入您的 json 中,如下所示:

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

对你的声音 url 做同样的事情。
还有!从长远来看,这将简化维护...如果有一天您发现 URL 损坏。
然后,可以像这样进行预加载:

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);
}

所以它不会在任何地方显示或播放...
但是浏览器会加载它。

您可能必须通过 CSS 隐藏音频播放器:

audio{
  display:none;
}

我做了一个CodePen demo以确保它正常工作。
json中只有3项...
图像和声音都非常小。
所以你不会真正注意到这个演示中的加载延迟。 ;)

我建议您将此脚本放在 document.ready() 包装器中...
setTimeout() 函数中,在文档准备好后 0.5 到 2 秒执行它。
所以页面的其余部分不会滞后。

关于javascript - 异步预加载 css 图像和声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44218320/

相关文章:

javascript - 使用 jQuery 显示的元素上的 CSS 转换问题

javascript - 在数组中搜索以 `+` 开头的括号

javascript - 如何在canvas和kineticjs中使用selenium进行拖放

javascript - 仅当父级具有类时单击

javascript - Chartjs 自定义刻度数字

html - HTML中div的对齐问题

css - 无法在 Bootstrap 中嵌入边缘动画

javascript - 阻止方法返回 'undefined'

javascript - 如何在用户重新加载页面时更新图像/ Logo ?

php - 当用户按下按钮时,如何从 View 中更改模型内的值?