Image preloader javascript, поддерживающий события
Я пытаюсь найти сценарий загрузчика изображений.
хотя я нашел несколько, ни один из них не поддерживает событие, которое запускается после завершения предварительной загрузки.
кто-нибудь знает какой-либо скрипт или плагин jQuery, который это сделает?
надеюсь, что этот вопрос подходит для stackoverflow - если нет, не стесняйтесь удалить его в одно мгновение.
4 ответов
вот функция, которая будет предварительно загружать изображения из массива и вызывать ваш обратный вызов, когда последний закончит:
function preloadImages(srcs, imgs, callback) {
var img;
var remaining = srcs.length;
for (var i = 0; i < srcs.length; i++) {
img = new Image();
img.onload = function() {
--remaining;
if (remaining <= 0) {
callback();
}
};
img.src = srcs[i];
imgs.push(img);
}
}
// then to call it, you would use this
var imageSrcs = ["src1", "src2", "src3", "src4"];
var images = [];
preloadImages(imageSrcs, images, myFunction);
и поскольку мы сейчас в возрасте использования обещаний для асинхронных операций, вот версия выше, которая использует обещания и уведомляет вызывающего абонента через стандартное обещание ES6:
function preloadImages(srcs) {
function loadImage(src) {
return new Promise(function(resolve, reject) {
var img = new Image();
img.onload = function() {
resolve(img);
};
img.onerror = img.onabort = function() {
reject(src);
};
img.src = src;
});
}
var promises = [];
for (var i = 0; i < srcs.length; i++) {
promises.push(loadImage(srcs[i]));
}
return Promise.all(promises);
}
preloadImages(["src1", "src2", "src3", "src4"]).then(function(imgs) {
// all images are loaded now and in the array imgs
}, function(errImg) {
// at least one image failed to load
});
и вот версия, использующая 2015 jQuery promises:
function preloadImages(srcs) {
function loadImage(src) {
return new $.Deferred(function(def) {
var img = new Image();
img.onload = function() {
def.resolve(img);
};
img.onerror = img.onabort = function() {
def.reject(src);
};
img.src = src;
}).promise();
}
var promises = [];
for (var i = 0; i < srcs.length; i++) {
promises.push(loadImage(srcs[i]));
}
return $.when.apply($, promises).then(function() {
// return results as a simple array rather than as separate arguments
return Array.prototype.slice.call(arguments);
});
}
preloadImages(["src1", "src2", "src3", "src4"]).then(function(imgs) {
// all images are loaded now and in the array imgs
}, function(errImg) {
// at least one image failed to load
});
Для более надежного решения рассмотрим это PRELOADER
функция с несколькими ответами (jsFiddle).
все просто:
в этом примере я передаю вызовы и хэш изображения внутри Object
литерал PRELOADER_OBJECT
, затем переопределение обратных вызовов внутри PRELOADER
:
// preloder object stores image hash
// and event handler callbacks
var PRELOADER_OBJECT = {
imgArray:"http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg".split(" "),
progressCallback : function( percent )
{
$( '#preloader_progress' ).html( 'preload progress complete : ' + percent + '%' );
console.log( 'preload progress complete : ', percent );
},
completeCallback : function( scope )
{
// hide preload indicator, do something when finished
console.log( 'preload complete!' );
$( '#preloader_modal' ).delay( 1000 ).animate( { opacity : 0 }, function( )
{
$( '.preload_class' ).each( function( index )
{
$( this ).delay( index * 100 ).animate( { opacity : 0 } );
} );
} );
}
/*Localize params and create PRELOADER object.
Needs to loadImages( ); iterate through hash and
call onPreloadProgress( ) and onPreloadComplete( )
each time until finished. If you're still within
bounds of the image hash, call progressCallback( )
recursively. When finished, fire onCompleteCallback( )*/
var PRELOADER = function( object )
{
// preloader modal overlay
this.modal = undefined;
// progress indicator container
this.progressIndicator = undefined;
// image preload progress
this.progress = undefined;
// progress callback
this.progressCallback = undefined;
// complete callback
this.completeCallback = undefined;
// hash to store key : value pairs for image paths
this.imgArray = undefined;
// store images in preloadArray
this.preloadArray = [];
// initialize and localize our data
this.initialize = function( )
{
// create preload indicator and overlay modal
this.createPreloaderModal( );
// image hash
this.imgArray = object.imgArray;
// progress callback event handler
this.progressCallback = object.progressCallback;
// complete callback event
this.completeCallback = object.completeCallback;
// load images
this.loadImages( );
};
this.progressCallback = function( ) {}; // function to override
this.completeCallback = function( ) {}; // function to override
// load images into DOM and fire callbacks
this.loadImages = function( )
{
var that = this;
// iterate through hash and place images into DOM
$.each( PRELOADER_OBJECT.imgArray, function( index, object )
{
this.image = $( "<img/>", { "src" : object, "class": "preload_class" } ).appendTo( 'body' );
// mark progress and call progressCallback( ) event handler
that.progress = Math.ceil( ( index / PRELOADER_OBJECT.imgArray.length ) * 100 );
that.progressCallback( this.progress );
that.preloadArray.push( this.image );
} );
// check for array bounds and call completeCallback( )
if ( PRELOADER_OBJECT.imgArray.length )
{
this.progressCallback( 100 );
this.completeCallback( this );
}
};
// create modal to display preload data
this.createPreloaderModal = function( )
{
this.modal = $( '<div/>', { 'id' : 'preloader_modal' } ).appendTo( 'body' );
this.progressIndicator = $( '<h1/>', { 'id' : 'preloader_progress' } ).appendTo( this.modal );
};
};
// trigger event chain when DOM loads
$( document ).ready( function( )
{
// instantiate PRELOADER instance and pass
// our JSON data model as a parameter
var preloader = new PRELOADER( PRELOADER_OBJECT );
// initialize preloader
preloader.initialize( );
} );
};
С нагрузкой места большой достаточно для того чтобы требовать preloader изображения, модальный дисплей текста смог легко быть доработан для того чтобы поддержать a на основе данных jQuery анимации.
предварительная загрузка и загрузка-одно и то же. Вы можете вставить изображение (создать новое или изменить атрибут "src" существующего), но скрыть элемент с помощью $("element").hide()
или что-то подобное. Перед этим прикрепите обработчик событий load следующим образом:
var images = ["src1", "src2", "src3", "src4"];
var len = images.length;
for(i=0; i<len; i++){
$("parent element").html('<img id="new-img" style="display:none;" src="'+images[i]+'"/>');
$("new-img").load(function(){
//Your image is now "preloaded"
//Now you can show the image, or do other stuff
$(this).show();
});
}
предварительная загрузка требует дополнительной работы, такой как создание новых элементов изображения, мониторинг их загрузки, а затем замена их существующими в DOM. Однако вы можете сделать это непосредственно на DOM <img>
элементы бесконечно много раз без их замены.
мы можем использовать Fetch API для доступа к изображениям, подождите, пока они не будут загружены в promise.all()
и затем за один раз просто замените src
атрибуты img
элементы в самых подходящее время с помощью window.requestAnimationFrame()
.
в следующем примере я освежаю src
атрибуты img
элементы 10 раз. В соответствии с задержкой я использую время, необходимое для загрузки 4 изображений из API. Поэтому, как только мы загрузили все изображения, я немедленно размещаю новый запрос, вызывая то же самое