#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 []; }
Комментариев нет:
Отправить комментарий