PageSourceSearch

https://azcapitoltimes.com/wp-content/plugins/slidedeck3-personal/js/jail.js?ver=4.5.1

js azcapitoltimes.com collected 2026-09-24 08:55:13 UTC 12,514 bytes, 452 lines download raw bytes

1/*
2 *  JAIL: jQuery Asynchronous Image Loader
3 *
4 * Copyright (c) 2011-12 Sebastiano Armeli-Battana (http://www.sebastianoarmelibattana.com)
5 *
6 * By Sebastiano Armeli-Battana (@sebarmeli)
7 * Licensed under the MIT license.
8 * https://github.com/sebarmeli/JAIL/blob/master/MIT-LICENSE.txt
9 *
10 * Tested with jQuery 1.3.2+ on FF 2+, Opera 10+, Safari 4+, Chrome 8+ on Win/Mac/Linux
11 * and IE 6/7/8 on Win.
12 *
13 * Contributor : Derek Lindahl - @dlindahl
14 *
15 * @link http://github.com/sebarmeli/JAIL
16 * @author Sebastiano Armeli-Battana
17 * @date 14/10/2012
18 * @version 1.0.0
19 *
20 */
21;
22( function( name, definition ) {
23
24	var theModule = definition( jQuery ),
25			hasDefine = typeof define === 'function' && define.amd;
26
27	if ( hasDefine ) {  // AMD module
28
29		define( name, ['jquery'], theModule );
30
31	} else { // assign 'jail' to global objects
32
33		( this.jQuery || this.$ || this )[name] = theModule;
34
35	}
36}( 'jail', function( $ ) {
37
38	var $window = $( window ),
39			// Defaults parameters
40			defaults = {
41				id: 'jail',
42				timeout: 1,
43				effect: false,
44				speed: 400,
45				triggerElement: null,
46				offset: 0,
47				event: 'load',
48				callback: null,
49				callbackAfterEachImage: null,
50				placeholder: false,
51				loadHiddenImages: false,
52				loadAllHorizontal: false
53			},
54	// current stack of images
55	currentStack = [],
56			// true if 'callback' fn is called
57			isCallbackDone = false;
58
59	/* 
60	 * Public function defining 'jail'
61	 *
62	 * @module jail
63	 * @param elems : images to load - jQuery elements
64	 * @param opts : configurations object
65	 */
66	$.jail = function( elems, opts ) {
67
68		var elements = elems || {},
69				options = $.extend( {}, defaults, opts );
70
71		// Initialize plugin
72		$.jail.prototype.init( elements, options );
73
74		// When the event is not specified the images will be loaded with a delay
75		if ( /^(load|scroll)/.test( options.event ) ) {
76			// 'load' event
77			$.jail.prototype.later.call( elements, options );
78		} else {
79			$.jail.prototype.onEvent.call( elements, options );
80		}
81	};
82
83	/* 
84	 * Method in charge of initializing the plugin, storing
85	 * the 'element triggering the image to load' in a data attribute 
86	 * for each image and displaying the placeholder image (if existing)
87	 *
88	 * @method init
89	 * @param {Array} elems Images to load - jQuery elements
90	 * @param {Object} opts Configurations object
91	 */
92	$.jail.prototype.init = function( elements, options ) {
93
94		// Store the selector triggering jail into 'triggerElem' data for the images selected 
95		elements.data( "triggerElem", ( options.triggerElement ) ? $( options.triggerElement ) : $window );
96
97		// Use a placeholder in case it is specified
98		if ( !!options.placeholder ) {
99			elements.each( function() {
100				$( this ).attr( "src", options.placeholder );
101			} );
102		}
103	};
104
105
106	/* 
107	 * Function called when 'event' is different from "load" or "scroll". Two scenarios:
108	 * a) Element triggering the images to be loaded (events available on the element: "click", "mouseover", "scroll")
109	 * b) Event on the image itself triggering the image to be loaded
110	 *
111	 * @param options : configurations object
112	 */
113	$.jail.prototype.onEvent = function( options ) {
114		var images = this;
115
116		if ( !!options.triggerElement ) {
117
118			// Event on the 'triggerElement' obj
119			_bindEvent( options, images );
120
121		} else {
122
123			// Event on the image itself
124			images.on( options.event + '.' + options.id, {options: options, images: images}, function( e ) {
125				var $img = $( this ),
126						options = e.data.options,
127						images = e.data.images;
128
129				currentStack = $.extend( {}, images );
130
131				// Load the image
132				_loadImage( options, $img );
133
134				// Image has been loaded so there is no need to listen anymore
135				$( e.currentTarget ).unbind( e.type + '.' + options.id );
136			} );
137		}
138	};
139
140	/* 
141	 * Method called when "event" is equals to "load" (default) or "scroll". The visible images will be 
142	 * loaded after a specified timeout (or after 1 ms). The scroll method will be bound to the window
143	 * to load  the images not visible onload.
144	 *
145	 * @param options : configurations object
146	 */
147	$.jail.prototype.later = function( options ) {
148		var images = this;
149
150		// After [timeout] has elapsed, load the visible images
151		setTimeout( function() {
152
153			currentStack = $.extend( {}, images );
154
155			//Load the visible ones
156			images.each( function() {
157				_loadImageIfVisible( options, this, images );
158			} );
159
160			// When images become available (scrolling or resizing), they will be loaded 
161			options.event = "scroll";
162			_bindEvent( options, images );
163
164		}, options.timeout );
165	};
166
167	/* 
168	 * Bind _bufferedEventListener() to the event on window/triggerElement. The handler is bound to 
169	 * resizing the window as well
170	 *
171	 * @param options : configurations object
172	 * @param images : images in the current stack
173	 */
174	function _bindEvent( options, images ) {
175		var triggerElem = false;
176
177		if ( !!images ) {
178			triggerElem = images.data( "triggerElem" );
179		}
180
181		// Check if there are images to load
182		if ( !!triggerElem && typeof triggerElem.on === "function" ) {
183			triggerElem.on( options.event + '.' + options.id, {options: options, images: images}, _bufferedEventListener );
184			$window.on( 'resize.' + options.id, {options: options, images: images}, _bufferedEventListener );
185		}
186	}
187
188	/* 
189	 * Remove any elements that have been loaded from the jQuery stack.
190	 * This should speed up subsequent calls by not having to iterate over the loaded elements.
191	 *
192	 * @param stack : current images stack
193	 */
194	function _purgeStack( stack ) {
195		// number of images not loaded
196		var i = 0;
197
198		if ( stack.length === 0 ) {
199			return;
200		}
201
202		// Check on existence of 'data-src' attribute to verify if the image has been loaded
203		while ( true ) {
204			if ( i === stack.length ) {
205				break;
206			} else {
207				if ( $( stack[i] ).attr( 'data-src' ) ) {
208					i++;
209				} else {
210					stack.splice( i, 1 );
211				}
212			}
213		}
214	}
215
216	/* 
217	 * Event handler for the images to be loaded. Function called when 
218	 * there is a triggerElement or when there are images to be loaded after scrolling 
219	 * or resizing window/container 
220	 *
221	 * @param e : event
222	 */
223	function _bufferedEventListener( e ) {
224		var images = e.data.images,
225				options = e.data.options;
226		// Don't set a timer if one is set.
227		if ( images.data( "poller" ) ) {
228			return;
229		}
230
231		images.data( 'poller', setTimeout( function() {
232
233			currentStack = $.extend( {}, images );
234			_purgeStack( currentStack );
235
236			// Load only the images left
237			$( currentStack ).each( function() {
238				if ( this === window ) {
239					return;
240				}
241				_loadImageIfVisible( options, this, currentStack );
242			} );
243
244			//Unbind when there are no images
245			if ( _isAllImagesLoaded( currentStack ) ) {
246				$( e.currentTarget ).unbind( e.type + '.' + options.id );
247				return;
248			}
249			// When images are not in the viewport, let's load them when they become available
250			else if ( options.event !== "scroll" ) {
251
252				// When images become available (scrolling or resizing), they will be loaded 
253				var container = ( /scroll/i.test( options.event ) ) ? images.data( "triggerElem" ) : $window;
254
255				options.event = "scroll";
256				images.data( "triggerElem", container );
257				_bindEvent( options, $( currentStack ) );
258			}
259			images.data( "poller", null );
260		}, options.timeout ) );
261	}
262
263	/* 
264	 * Check if all the images are loaded
265	 *
266	 * @param images : images under analysis
267	 * @return boolean
268	 */
269	function _isAllImagesLoaded( images ) {
270		var bool = true;
271
272		$( images ).each( function() {
273			if ( !!$( this ).attr( "data-src" ) ) {
274				bool = false;
275			}
276		} );
277		return bool;
278	}
279
280	/* 
281	 * Load the image if visible in the viewport
282	 *
283	 * @param options : configurations object
284	 * @param image : image under analysis
285	 * @param images : list of images to load
286	 */
287	function _loadImageIfVisible( options, image, images ) {
288		var $img = $( image ),
289				container = ( /scroll/i.test( options.event ) ) ? images.data( "triggerElem" ) : $window,
290				isVisible = true;
291
292		// If don't you want to load hidden images (default beahviour)
293		if ( !options.loadHiddenImages ) {
294			isVisible = _isVisibleInContainer( $img, container, options ) && $img.is( ":visible" );
295		}
296
297		// Load the image if it is not hidden and visible in the screen
298		if ( isVisible && _isInTheScreen( container, $img, options.offset, options.loadAllHorizontal ) ) {
299			_loadImage( options, $img );
300		}
301	}
302
303	/* 
304	 * Function that returns true if the image is visible inside the "window" (or specified container element)
305	 *
306	 * @param $ct : container - jQuery obj
307	 * @param $img : image selected - jQuery obj
308	 * @param optionOffset : offset
309	 */
310	function _isInTheScreen( $ct, $img, optionOffset, loadAllHorizontal ) {
311		if ( loadAllHorizontal ) {
312			return true;
313		} else {
314			var is_ct_window = $ct[0] === window,
315					ct_offset = ( is_ct_window ? {top: 0, left: 0} : $ct.offset() ),
316					ct_top = ct_offset.top + ( is_ct_window ? $ct.scrollTop() : 0 ),
317					ct_left = ct_offset.left + ( is_ct_window ? $ct.scrollLeft() : 0 ),
318					ct_right = ct_left + $ct.width(),
319					ct_bottom = ct_top + $ct.height(),
320					img_offset = $img.offset(),
321					img_width = $img.width(),
322					img_height = $img.height();
323
324			return ( ct_top - optionOffset ) <= ( img_offset.top + img_height ) &&
325					( ct_bottom + optionOffset ) >= img_offset.top &&
326					( ct_left - optionOffset ) <= ( img_offset.left + img_width ) &&
327					( ct_right + optionOffset ) >= img_offset.left;
328		}
329	}
330
331	/* 
332	 * Main function --> Load the images copying the "data-href" attribute into the "src" attribute
333	 *
334	 * @param options : configurations object
335	 * @param $img : image selected - jQuery obj
336	 */
337	function _loadImage( options, $img ) {
338
339		// Use cache Image object to show images only when ready
340		var cache = new Image();
341
342		cache.onload = function() {
343			$img.hide().attr( "src", cache.src );
344
345			$img.removeAttr( 'data-src' );
346			// Images loaded with some effect if existing
347			if ( options.effect ) {
348
349				if ( options.speed ) {
350					$img[options.effect]( options.speed );
351				} else {
352					$img[options.effect]();
353				}
354				$img.css( "opacity", 1 );
355				$img.show();
356			} else {
357				$img.show();
358			}
359
360			_purgeStack( currentStack );
361
362			// Callback after each image is loaded
363			if ( !!options.callbackAfterEachImage ) {
364				options.callbackAfterEachImage.call( this, $img, options );
365			}
366
367			if ( _isAllImagesLoaded( currentStack ) && !!options.callback && !isCallbackDone ) {
368				options.callback.call( $.jail, options );
369				isCallbackDone = true;
370			}
371		};
372
373		/*
374		 * Basic on error handler. For now we limit
375		 * the plugin to exectute any callback passed
376		 * in the options object. Let the developer
377		 * decide what to do with it.
378		 */
379		cache.onerror = function() {
380
381			if ( !( 'error' in options ) ) {
382				return;
383			}
384
385			var args = Array.prototype.slice.call( arguments, 0 );
386			args = [$img, options].concat( args );
387			options.error.apply( $.jail, args );
388		};
389
390		cache.src = $img.attr( "data-src" );
391	}
392
393	/* 
394	 * Return if the image is visible inside a "container" / window. There are checks around
395	 * "visibility" CSS property and around "overflow" property of the "container"
396	 *
397	 * @param $img : image selected - jQuery obj
398	 * @param container : container object
399	 * @param options : configurations object
400	 */
401	function _isVisibleInContainer( $img, container, options ) {
402
403		var parent = $img.parent(),
404				isVisible = true;
405
406		while ( parent.length && parent.get( 0 ).nodeName.toUpperCase() !== "BODY" ) {
407			// Consider the 'overflow' property
408			if ( parent.css( "overflow" ) === "hidden" ) {
409				if ( !_isInTheScreen( parent, $img, options.offset, options.loadAllHorizontal ) ) {
410					isVisible = false;
411					break;
412				}
413			} else if ( parent.css( "overflow" ) === "scroll" ) {
414				if ( !_isInTheScreen( parent, $img, options.offset, options.loadAllHorizontal ) ) {
415					isVisible = false;
416					$( currentStack ).data( "triggerElem", parent );
417
418					options.event = "scroll";
419					_bindEvent( options, $( currentStack ) );
420					break;
421				}
422			}
423
424			if ( parent.css( "visibility" ) === "hidden" || $img.css( "visibility" ) === "hidden" ) {
425				isVisible = false;
426				break;
427			}
428
429			// If container is not the window, and the parent is the container, exit from the loop
430			if ( container !== $window && parent === container ) {
431				break;
432			}
433
434			parent = parent.parent();
435		}
436
437		return isVisible;
438	}
439
440	// Small wrapper
441	$.fn.jail = function( options ) {
442
443		new $.jail( this, options );
444
445		// Empty current stack
446		currentStack = [];
447
448		return this;
449	};
450
451	return $.jail;
452} ) );

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.