/ajax/libs/foundation/3.2.5/javascripts/jquery.foundation.clearing.js
JavaScript | 413 lines | 310 code | 81 blank | 22 comment | 61 complexity | 2bb064074063dd5bbcd6ce1274885f63 MD5 | raw file
- /*
- * jQuery Foundation Clearing 1.2.1
- * http://foundation.zurb.com
- * Copyright 2012, ZURB
- * Free to use under the MIT license.
- * http://www.opensource.org/licenses/mit-license.php
- */
- /*jslint unparam: true, browser: true, indent: 2 */
- ;(function ($, window, document, undefined) {
- 'use strict';
- var defaults = {
- templates : {
- viewing : '<a href="#" class="clearing-close">×</a>' +
- '<div class="visible-img" style="display: none"><img src="#">' +
- '<p class="clearing-caption"></p><a href="#" class="clearing-main-left"></a>' +
- '<a href="#" class="clearing-main-right"></a></div>'
- },
- // comma delimited list of selectors that, on click, will close clearing,
- // add 'div.clearing-blackout, div.visible-img' to close on background click
- close_selectors : 'a.clearing-close',
- // event initializers and locks
- initialized : false,
- locked : false
- },
- cl = {
- init : function (options, extendMethods) {
- return this.find('ul[data-clearing]').each(function () {
- var doc = $(document),
- $el = $(this),
- options = options || {},
- extendMethods = extendMethods || {},
- settings = $el.data('fndtn.clearing.settings');
- if (!settings) {
- options.$parent = $el.parent();
- $el.data('fndtn.clearing.settings', $.extend({}, defaults, options));
- cl.assemble($el.find('li'));
- if (!defaults.initialized) {
- cl.events($el);
- if (Modernizr.touch) cl.swipe_events();
- }
- }
- });
- },
- events : function (el) {
- var settings = el.data('fndtn.clearing.settings');
- $(document)
- .on('click.fndtn.clearing', 'ul[data-clearing] li', function (e, current, target) {
- var current = current || $(this),
- target = target || current,
- settings = current.parent().data('fndtn.clearing.settings');
- e.preventDefault();
- if (!settings) {
- current.parent().foundationClearing();
- }
- // set current and target to the clicked li if not otherwise defined.
- cl.open($(e.target), current, target);
- cl.update_paddles(target);
- })
- .on('click.fndtn.clearing', '.clearing-main-right', function (e) { cl.nav(e, 'next') })
- .on('click.fndtn.clearing', '.clearing-main-left', function (e) { cl.nav(e, 'prev') })
- .on('click.fndtn.clearing', settings.close_selectors, this.close)
- .on('keydown.fndtn.clearing', this.keydown);
- $(window).on('resize.fndtn.clearing', this.resize);
- defaults.initialized = true;
- },
- swipe_events : function () {
- $(document)
- .bind('swipeleft', 'ul[data-clearing]', function (e) { cl.nav(e, 'next') })
- .bind('swiperight', 'ul[data-clearing]', function (e) { cl.nav(e, 'prev') })
- .bind('movestart', 'ul[data-clearing]', function (e) {
- if ((e.distX > e.distY && e.distX < -e.distY) ||
- (e.distX < e.distY && e.distX > -e.distY)) {
- e.preventDefault();
- }
- });
- },
- assemble : function ($li) {
- var $el = $li.parent(),
- settings = $el.data('fndtn.clearing.settings'),
- grid = $el.detach(),
- data = {
- grid: '<div class="carousel">' + this.outerHTML(grid[0]) + '</div>',
- viewing: settings.templates.viewing
- },
- wrapper = '<div class="clearing-assembled"><div>' + data.viewing + data.grid + '</div></div>';
- return settings.$parent.append(wrapper);
- },
- open : function ($image, current, target) {
- var root = target.closest('.clearing-assembled'),
- container = root.find('div:first'),
- visible_image = container.find('.visible-img'),
- image = visible_image.find('img').not($image);
- if (!cl.locked()) {
- // set the image to the selected thumbnail
- image.attr('src', this.load($image));
- image.loaded(function () {
- // toggle the gallery if not visible
- root.addClass('clearing-blackout');
- container.addClass('clearing-container');
- this.caption(visible_image.find('.clearing-caption'), $image);
- visible_image.show();
- this.fix_height(target);
- this.center(image);
- // shift the thumbnails if necessary
- this.shift(current, target, function () {
- target.siblings().removeClass('visible');
- target.addClass('visible');
- });
- }.bind(this));
- }
- },
- close : function (e) {
- e.preventDefault();
- var root = (function (target) {
- if (/blackout/.test(target.selector)) {
- return target;
- } else {
- return target.closest('.clearing-blackout');
- }
- }($(this))), container, visible_image;
- if (this === e.target && root) {
- container = root.find('div:first'),
- visible_image = container.find('.visible-img');
- defaults.prev_index = 0;
- root.find('ul[data-clearing]').attr('style', '')
- root.removeClass('clearing-blackout');
- container.removeClass('clearing-container');
- visible_image.hide();
- }
- return false;
- },
- keydown : function (e) {
- var clearing = $('.clearing-blackout').find('ul[data-clearing]');
- if (e.which === 39) cl.go(clearing, 'next');
- if (e.which === 37) cl.go(clearing, 'prev');
- if (e.which === 27) $('a.clearing-close').trigger('click');
- },
- nav : function (e, direction) {
- var clearing = $('.clearing-blackout').find('ul[data-clearing]');
- e.preventDefault();
- this.go(clearing, direction);
- },
- resize : function () {
- var image = $('.clearing-blackout .visible-img').find('img');
- if (image.length > 0) {
- cl.center(image);
- }
- },
- fix_height : function (target) {
- var lis = target.siblings();
- lis.each(function () {
- var li = $(this),
- image = li.find('img');
- if (li.height() > image.outerHeight()) {
- li.addClass('fix-height');
- }
- })
- .closest('ul').width(lis.length * 100 + '%');
- },
- update_paddles : function (target) {
- var visible_image = target.closest('.carousel').siblings('.visible-img');
- if (target.next().length > 0) {
- visible_image.find('.clearing-main-right').removeClass('disabled');
- } else {
- visible_image.find('.clearing-main-right').addClass('disabled');
- }
- if (target.prev().length > 0) {
- visible_image.find('.clearing-main-left').removeClass('disabled');
- } else {
- visible_image.find('.clearing-main-left').addClass('disabled');
- }
- },
- load : function ($image) {
- var href = $image.parent().attr('href');
- this.preload($image);
- if (href) return href;
- return $image.attr('src');
- },
- preload : function ($image) {
- this.img($image.closest('li').next());
- this.img($image.closest('li').prev());
- },
- img : function (img) {
- if (img.length > 0) {
- var new_img = new Image(),
- new_a = img.find('a');
- if (new_a.length > 0) {
- new_img.src = new_a.attr('href');
- } else {
- new_img.src = img.find('img').attr('src');
- }
- }
- },
- caption : function (container, $image) {
- var caption = $image.data('caption');
- if (caption) {
- container.text(caption).show();
- } else {
- container.text('').hide();
- }
- },
- go : function ($ul, direction) {
- var current = $ul.find('.visible'),
- target = current[direction]();
- if (target.length > 0) {
- target.find('img').trigger('click', [current, target]);
- }
- },
- shift : function (current, target, callback) {
- var clearing = target.parent(),
- old_index = defaults.prev_index,
- direction = this.direction(clearing, current, target),
- left = parseInt(clearing.css('left'), 10),
- width = target.outerWidth(),
- skip_shift;
- // we use jQuery animate instead of CSS transitions because we
- // need a callback to unlock the next animation
- if (target.index() !== old_index && !/skip/.test(direction)){
- if (/left/.test(direction)) {
- this.lock();
- clearing.animate({left : left + width}, 300, this.unlock);
- } else if (/right/.test(direction)) {
- this.lock();
- clearing.animate({left : left - width}, 300, this.unlock);
- }
- } else if (/skip/.test(direction)) {
- // the target image is not adjacent to the current image, so
- // do we scroll right or not
- skip_shift = target.index() - defaults.up_count;
- this.lock();
- if (skip_shift > 0) {
- clearing.animate({left : -(skip_shift * width)}, 300, this.unlock);
- } else {
- clearing.animate({left : 0}, 300, this.unlock);
- }
- }
- callback();
- },
- lock : function () {
- defaults.locked = true;
- },
- unlock : function () {
- defaults.locked = false;
- },
- locked : function () {
- return defaults.locked;
- },
- direction : function ($el, current, target) {
- var lis = $el.find('li'),
- li_width = lis.outerWidth() + (lis.outerWidth() / 4),
- up_count = Math.floor($('.clearing-container').outerWidth() / li_width) - 1,
- target_index = lis.index(target),
- response;
- defaults.up_count = up_count;
- if (this.adjacent(defaults.prev_index, target_index)) {
- if ((target_index > up_count) && target_index > defaults.prev_index) {
- response = 'right';
- } else if ((target_index > up_count - 1) && target_index <= defaults.prev_index) {
- response = 'left';
- } else {
- response = false;
- }
- } else {
- response = 'skip';
- }
- defaults.prev_index = target_index;
- return response;
- },
- adjacent : function (current_index, target_index) {
- for (var i = target_index + 1; i >= target_index - 1; i--) {
- if (i === current_index) return true;
- }
- return false;
- },
- center : function (target) {
- target.css({
- marginLeft : -(target.outerWidth() / 2),
- marginTop : -(target.outerHeight() / 2)
- });
- },
- outerHTML : function (el) {
- // support FireFox < 11
- return el.outerHTML || new XMLSerializer().serializeToString(el);
- }
- };
- $.fn.foundationClearing = function (method) {
- if (cl[method]) {
- return cl[method].apply(this, Array.prototype.slice.call(arguments, 1));
- } else if (typeof method === 'object' || !method) {
- return cl.init.apply(this, arguments);
- } else {
- $.error('Method ' + method + ' does not exist on jQuery.foundationClearing');
- }
- };
- // jquery.imageready.js
- // @weblinc, @jsantell, (c) 2012
- (function( $ ) {
- $.fn.loaded = function ( callback, userSettings ) {
- var
- options = $.extend( {}, $.fn.loaded.defaults, userSettings ),
- $images = this.find( 'img' ).add( this.filter( 'img' ) ),
- unloadedImages = $images.length;
- function loaded () {
- unloadedImages -= 1;
- !unloadedImages && callback();
- }
- function bindLoad () {
- this.one( 'load', loaded );
- if ( $.browser.msie ) {
- var
- src = this.attr( 'src' ),
- param = src.match( /\?/ ) ? '&' : '?';
- param += options.cachePrefix + '=' + ( new Date() ).getTime();
- this.attr( 'src', src + param );
- }
- }
- return $images.each(function () {
- var $this = $( this );
- if ( !$this.attr( 'src' ) ) {
- loaded();
- return;
- }
- this.complete || this.readyState === 4 ?
- loaded() :
- bindLoad.call( $this );
- });
- };
- $.fn.loaded.defaults = {
- cachePrefix: 'random'
- };
- }(jQuery));
- }(jQuery, this, this.document));