#javascript #jquery
Задача состоит вот в чем.
Есть сайт с элементами меню, каждый элемент подгружает что-то одно:
Секвенции (Например моделька 360 состоящая из набора фотографий)
Видео
Просто картинка
Не напрягая лишним функционалом, просто сведу к минимуму:
Есть кнопка при какой необходимо, чтобы все секвенции, картинки или даже видео подгружались
в памяти и при воспроизведении не глючили.
Какие самые благоприятные варианты реализовать это без лагов?
Буду рад любой помощи.
Реализовал загрузку всех изображений в кэш, лаги всё равно есть. Поэтому уже обратился
сюда.
Код загрузки изображений в кэш:
!function ($) {
/**
* В поданный на вход элемент создается div, куда будут помещены изображения.
* Данную функцию вызывает массив, в каком содержаться пути к изображениям.
* @param el Элемент, куда будет помещен блок с кэшем
* @param id Уникальное имя для блока с кэшем
*/
$.fn.preload = function (el, id) {
// Если элемента с указанным идентификатором не существует, то загружаем в кэш
if (!el.find('#' + id).exists()) {
// Формируем блок, где будут лежать указанные изображения
$("").hide().appendTo(el);
// Проходим каждый элемент массива и формируем изображение
this.each(function () {
$('
').attr("src", this).appendTo("#" + id);
});
}
};
}(window.jQuery);
/**
* Загрузка переданного элемента в кэш (Осуществляет загрузку секвенций и картинок)
* @param el Dom-element
* @param index Индекс массива
*/
function preload_item(el, index) {
var id = el.attr('data-id'), // Указанный идентификатор для элемента
src, // Тут будет храниться путь к картинке
frames, // Кол-во фреймов, какие будут записаны в кэш
arr = [], // Массив, в каком будет храниться путь к каждому изображению
img_name, // Будет храниться только имя изображения с удаленным постфиксом
directory; // Будет храниться папка, в какой будут все изображения
// Определяем тип контента, если секвенции, то много изображений, иначе одно
изображение
switch (el.attr('data-content')) {
case 'sequence':
src = el.attr("data-path");
frames = parseInt(el.attr('data-frames'));
// Записываем каждый путь к фрейму, для записи в кэш
for (var i = 1; i < frames + 1; i++) {
img_name = src.split('/')[src.split('/').length - 1];
directory = src.split('/').slice(0, -1).join("/");
arr.push(directory + "/" + img_name.split('_')[0] + "_" + i + "."
+ img_name.split('.')[1])
}
// Записываем в кэш и передаем элемент в каком будет содержаться images_cache
и уникальное имя для него
$(arr).preload(content, img_name.split('_')[0] + id);
break;
case 'image':
// Костыль небольшой.
// Получаем путь к изображению где лежать с мал. разрешением и заменяем
на папку, где лежать с большим разрешением.
src = el.find('img').attr("src").replace('colors_small', 'colors_big');
// Формируем путь к изображению
img_name = src.split('/')[src.split('/').length - 1];
directory = src.split('/').slice(0, -1).join("/");
arr.push(directory + "/" + img_name);
// Записываем в кэш и передаем те же данные
$(arr).preload(content, img_name.split('.')[0] + id);
break;
}
// Получаем список все img, какие не успели загрузиться
var images_not_loaded = $(".images_cache > img").not(function () {
return this.complete;
});
var count = images_not_loaded.length;
// Если кол-во > 0
if (count) {
// Записываем их
images_not_loaded.load(function () {
count--;
// Если уже нечего записывать и "левая переменная"
if (!count && index === ids.length - 1 && startAnimate) {
// Что-то делаем
}
});
} else {
// Если уже нечего записывать и "левая переменная"
if (index === ids.length - 1 && startAnimate) {
// Что-то делаем
}
}
}
Ответы
Ответ 1
Загружайте изображения через new Image(); .src даст вам путь. .onload создаст событие окончания загрузки - потом устанавливайте в требуемый вам div. Как полагаю, часть проблем у вас от того, что вы все добавляете в DOM, что также нагружает браузер. Как пример, используйте вот такой вариант: var images = {}; // Массив изображений function preload(el){ var id = el.attr('data-id'); var content = el.attr('data-content'); var obj = { loaded: 0, images: [] }; var src = el.attr('data-path'); /// тут непонятно как вы генерируете пути var arr = (content === 'sequence') ? getImageUrlsFromSequenceData() : getImageUrlsFromImageData(); /// но предположим в конце у нас их будет массив arr arr.forEach(function(item){ //создаем элемент Image var image = new Image(); //устанавливаем событие для получения того, что оно загрузилось //количество незагруженных вы можете получить через obj.images.length-obj.loaded image.onLoad=getActionOnLoad(obj); //назначаем урл image.src=item; //добавляем в массив obj.images.push(image); }); //добавляем в ссылочный массив images[id] = obj; } function getActionOnLoad(obj){ return (function(){ obj.loaded++; //тут еще можно вызывать требуемый нам каллбек, если loaded //достигло images.length. его можно добавить в параметры прелоадера }); } function getImageUrlsFromSequenceData(data){ //тут вы генерируете ссылки для sequence return []; } function getImageUrlsFromImageData(data){ //тут вы генерируете ссылки для Image return []; }
Комментариев нет:
Отправить комментарий