1(function($) { 2 3"use strict"; 4 5/** 6 * jQuery.imageloader 7 * (C) 2012, Takashi Mizohata 8 * http://beatak.github.com/jquery-imageloader/ 9 * MIT LICENSE 10 */ 11 12var DEFAULT_OPTIONS = { 13 selector: '', 14 dataattr: 'src', 15 background: false, 16 each: null, 17 eacherror: null, 18 callback: null, 19 timeout: 5000 20}; 21 22var init = function (_i, self, opts) { 23 var q = Queue.getInstance(); 24 var $this = $(self); 25 var defaults = $.extend({}, DEFAULT_OPTIONS, opts || {}); 26 var ns = '_' + ('' + (new Date()).valueOf()).slice(-7); 27 var $elms; 28 var len = 0; 29 30 if (defaults.selector === '' && $this.data(defaults.dataattr) ) { 31 $elms = $this; 32 len = 1; 33 } 34 else { 35 $elms = $this.find([defaults.selector, '[data-', defaults.dataattr, ']'].join('')); 36 len = $elms.length; 37 } 38 39 $this.data( 40 ns, 41 { 42 each: defaults.each, 43 eacherror: defaults.eacherror, 44 callback: defaults.callback, 45 isLoading: true, 46 loadedImageCounter: 0, 47 length: len 48 } 49 ); 50 51 if (len === 0) { 52 finishImageLoad(self, ns); 53 } 54 else { 55 $elms.each( 56 function (i, elm) { 57 q.add(buildImageLoadFunc(elm, self, ns, defaults.background, defaults.dataattr, defaults.timeout)); 58 } 59 ); 60 // console.log(['we are gonna load ', len, ' image(s) on ', ns].join('')); 61 $this.on('loadImage.' + ns, onLoadImage); 62 q.run(); 63 } 64 return self; 65}; 66 67// =================================================================== 68 69var onLoadImage = function (ev, elm, img, isError) { 70 // console.log('onLoadImage: ', ev.namespace); 71 var parent = ev.currentTarget; 72 var defaults = $(parent).data(ev.namespace); 73 if (!defaults.isLoading) { 74 // console.log('onLoadImage: is not loading but still called?'); 75 return; 76 } 77 if (isError) { 78 if (typeof defaults.eacherror === 'function') { 79 defaults.eacherror(elm); 80 } 81 else { 82 if (elm.parentNode !== null) { 83 elm.parentNode.removeChild(elm); 84 } 85 } 86 } 87 else if (typeof defaults.each === 'function') { 88 defaults.each(elm, img); 89 } 90 ++defaults.loadedImageCounter; 91 if (defaults.loadedImageCounter >= defaults.length) { 92 finishImageLoad(parent, ev.namespace); 93 } 94}; 95 96var finishImageLoad = function (parent, ns) { 97 // console.log('finishImageLoad: ', ns); 98 var $parent = $(parent); 99 var data = $parent.data(); 100 var callback = data[ns].callback; 101 $parent.off('loadImage.' + ns, onLoadImage); 102 delete data[ns]; 103 if (typeof callback === 'function') { 104 setTimeout( 105 function () { 106 callback(parent); 107 }, 108 $.imageloader.queueInterval * 2 109 ); 110 } 111}; 112 113var buildImageLoadFunc = function (elm, parent, namespace, isBg, attr, milsec_timeout) { 114 var $elm = $(elm); 115 var src = $elm.data(attr); 116 var hasFinished = false; 117 118 var onFinishLoagImage = function (ev, img) { 119 // delete attribute 120 $elm.removeAttr( ['data-', attr].join('') ); 121 $(parent).triggerHandler('loadImage.' + namespace, [elm, img, (ev && ev.type === 'error')]); 122 }; 123 124 return function () { 125 var timer_handler; 126 var $img = $('<img />'); // this statement is kinda silly, but IE needs this separated. 127 $img 128 .bind( 129 'error', 130 function (ev) { 131 hasFinished = true; 132 clearTimeout(timer_handler); 133 $(this).unbind('error').unbind('load'); 134 onFinishLoagImage(ev); 135 } 136 ) 137 .bind( 138 'load', 139 function(ev) { 140 hasFinished = true; 141 clearTimeout(timer_handler); 142 $(this).unbind('error').unbind('load'); 143 if (isBg) { 144 $elm.css('background-image', ['url(', src, ')'].join('')); 145 } 146 else { 147 $elm.attr('src', src); 148 } 149 onFinishLoagImage(ev, $img[0]); 150 } 151 ) 152 .attr('src', src); 153 timer_handler = setTimeout( 154 function () { 155 if (hasFinished === false) { 156 // console.log('timeout'); 157 $img.trigger('error'); 158 } 159 }, 160 milsec_timeout 161 ); 162 }; 163}; 164 165// =================================================================== 166 167var _queue_instance_; 168var Queue = { 169 getInstance: function () { 170 if (_queue_instance_ instanceof QueueImpl === false) { 171 _queue_instance_ = new QueueImpl(); 172 } 173 return _queue_instance_; 174 } 175}; 176 177var QueueImpl = function () { 178 this.index = 0; 179 this.queue = []; 180 this.isRunning = false;
181}; 182 183QueueImpl.prototype.add = function (func) { 184 if (typeof func !== 'function') { 185 throw new Error('you can only pass function.'); 186 } 187 this.queue.push(func); 188}; 189 190QueueImpl.prototype.run = function (firenow) { 191 var run = $.proxy(this.run, this); 192 firenow = firenow || false; 193 if (this.isRunning && !firenow) { 194 return; 195 } 196 this.isRunning = true; 197 this.queue[this.index++](); 198 if (this.index < this.queue.length) { 199 setTimeout( 200 function () { 201 run(true); 202 }, 203 $.imageloader.queueInterval 204 ); 205 } 206 else { 207 this.isRunning = false; 208 } 209}; 210 211// =================================================================== 212 213$.imageloader = { 214 queueInterval: 17 215}; 216 217$.fn.imageloader = function (opts) { 218 return this.each( 219 function (i, elm) { 220 init(i, elm, opts); 221 } 222 ); 223}; 224 225})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.