-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathjquery.preload.js
More file actions
161 lines (149 loc) · 5.35 KB
/
jquery.preload.js
File metadata and controls
161 lines (149 loc) · 5.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/**
* jQuery.Preload
* Copyright (c) 2008-2016 Ariel Flesler - aflesler<a>gmail<d>com | http://flesler.blogspot.com
* Licensed under MIT
* http://flesler.blogspot.com.ar/2008/01/jquerypreload.html
* @projectDescription Multi-functional image preloader plugin for jQuery
* @author Ariel Flesler
* @version 1.1.0
*
* @id jQuery.preload
* @param {String, jQuery, Array< String, <a>, <link>, <img> >} original Collection of sources to preload
* @param {Object} settings Hash of settings.
*
* @id jQuery.fn.preload
* @param {Object} settings Hash of settings.
* @return {jQuery} Returns the same jQuery object, for chaining.
*
* @example Link Mode:
* $.preload( '#images a' );
*
* @example Rollover Mode:
* $.preload( '#images img', {
* find:/\.(gif|jpg)/,
* replace:'_over.$1'
* });
*
* @example Src Mode:
* $.preload( [ 'red', 'blue', 'yellow' ], {
* base:'images/colors/',
* ext:'.jpg'
* });
*
* @example Placeholder Mode:
* $.preload( '#images img', {
* placeholder:'placeholder.jpg',
* notFound:'notfound.jpg'
* });
*
* @example Placeholder+Rollover Mode(High res):
* $.preload( '#images img', {
* placeholder:true,
* find:/\.(gif|jpg)/,
* replace:'_high.$1'
* });
*/
;(function( $ ){
var $preload = $.preload = function( original, settings ){
if( original.split ) // selector
original = $(original);
settings = $.extend( {}, $preload.defaults, settings );
var sources = $.map( original, function( source ){
if( !source )
return; // skip
if( source.split ) // URL Mode
return settings.base + source + settings.ext;
var url = settings.srcAttribute ? $(source).attr(settings.srcAttribute) : source.src || source.href; // save the original source
if( typeof settings.placeholder == 'string' && source.src ) // Placeholder Mode, if it's an image, set it.
source.src = settings.placeholder;
if( url && settings.find ) // Rollover mode
url = url.replace( settings.find, settings.replace );
return url || null; // skip if empty string
});
var data = {
loaded:0, // how many were loaded successfully
failed:0, // how many urls failed
next:0, // which one's the next image to load (index)
done:0, // how many urls were tried
/*
index:0, // index of the related image
found:false, // whether the last one was successful
*/
total:sources.length // how many images are being preloaded overall
};
if( !data.total ) // nothing to preload
return finish();
var imgs = $(Array(settings.threshold+1).join('<img/>'))
.on('load',handler).on('error',handler).bind('abort',handler).each(fetch);
function handler( e ){
data.element = this;
data.found = e.type == 'load';
data.image = this.src;
data.index = this.index;
var orig = data.original = original[this.index];
data[data.found?'loaded':'failed']++;
data.done++;
// This will ensure that the images aren't "un-cached" after a while
if( settings.enforceCache )
$preload.cache.push(
$('<img/>').attr('src',data.image)[0]
);
if( settings.placeholder && orig.src ) // special case when on placeholder mode
orig.src = data.found ? data.image : settings.notFound || orig.src;
if( settings.onComplete )
settings.onComplete( data );
if( data.done < data.total ) // let's continue
fetch( 0, this );
else{ // we are finished
if( imgs && imgs.unbind )
imgs.unbind('load').unbind('error').unbind('abort'); // cleanup
imgs = null;
finish();
}
};
function fetch( i, img, retry ){
// IE problem, can't preload more than 15
if( img.attachEvent /* msie */ && data.next && data.next % $preload.gap == 0 && !retry ){
setTimeout(function(){ fetch( i, img, true ); }, 0);
return false;
}
if( data.next == data.total ) return false; // no more to fetch
img.index = data.next; // save it, we'll need it.
img.src = sources[data.next++];
if( settings.onRequest ){
data.index = img.index;
data.element = img;
data.image = img.src;
data.original = original[data.next-1];
settings.onRequest( data );
}
};
function finish(){
if( settings.onFinish )
settings.onFinish( data );
};
};
// each time we load this amount and it's IE, we must rest for a while, make it lower if you get stack overflow.
$preload.gap = 14;
$preload.cache = [];
$preload.defaults = {
threshold:2, // how many images to load simultaneously
base:'', // URL mode: a base url can be specified, it is prepended to all string urls
ext:'', // URL mode:same as base, but it's appended after the original url.
replace:'' // Rollover mode: replacement (can be left empty)
/*
srcAttribute: null, // allow to define attribute to get url from
enforceCache: false, // If true, the plugin will save a copy of the images in $.preload.cache
find:null, // Rollover mode: a string or regex for the replacement
notFound:'' // Placeholder Mode: Optional url of an image to use when the original wasn't found
placeholder:'', // Placeholder Mode: url of an image to set while loading
onRequest:function( data ){ ... }, // callback called every time a new url is requested
onComplete:function( data ){ ... }, // callback called every time a response is received(successful or not)
onFinish:function( data ){ ... } // callback called after all the images were loaded(or failed)
*/
};
$.fn.preload = function( settings ){
$preload( this, settings );
return this;
};
})( jQuery );