481 lines
15 KiB
JavaScript
481 lines
15 KiB
JavaScript
/*
|
|
* jQuery Foundation Clearing 1.0
|
|
* 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, 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>'
|
|
},
|
|
initialized : false,
|
|
locked : false
|
|
},
|
|
|
|
superMethods = {},
|
|
|
|
methods = {
|
|
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));
|
|
|
|
// developer goodness experiment
|
|
methods.extend(methods, extendMethods);
|
|
|
|
// if the gallery hasn't been built yet...build it
|
|
methods.assemble($el.find('li'));
|
|
|
|
if (!defaults.initialized) methods.events();
|
|
|
|
}
|
|
});
|
|
},
|
|
|
|
events : function () {
|
|
var doc = $(document);
|
|
|
|
doc.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.
|
|
methods.open($(e.target), current, target);
|
|
methods.update_paddles(target);
|
|
});
|
|
|
|
$(window).on('resize.fndtn.clearing', function () {
|
|
var image = $('.clearing-blackout .visible-img').find('img');
|
|
|
|
if (image.length > 0) {
|
|
methods.center(image);
|
|
}
|
|
});
|
|
|
|
doc.on('click.fndtn.clearing', '.clearing-main-right', function (e) {
|
|
var clearing = $('.clearing-blackout').find('ul[data-clearing]');
|
|
|
|
e.preventDefault();
|
|
methods.go(clearing, 'next');
|
|
});
|
|
|
|
doc.on('click.fndtn.clearing', '.clearing-main-left', function (e) {
|
|
var clearing = $('.clearing-blackout').find('ul[data-clearing]');
|
|
|
|
e.preventDefault();
|
|
methods.go(clearing, 'prev');
|
|
});
|
|
|
|
doc.on('click.fndtn.clearing', 'a.clearing-close, div.clearing-blackout, div.visible-img', function (e) {
|
|
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;
|
|
});
|
|
|
|
// should specify a target selector
|
|
doc.on('keydown.fndtn.clearing', function (e) {
|
|
var clearing = $('.clearing-blackout').find('ul[data-clearing]');
|
|
|
|
// right
|
|
if (e.which === 39) {
|
|
methods.go(clearing, 'next');
|
|
}
|
|
|
|
// left
|
|
if (e.which === 37) {
|
|
methods.go(clearing, 'prev');
|
|
}
|
|
|
|
if (e.which === 27) {
|
|
$('a.clearing-close').trigger('click');
|
|
}
|
|
});
|
|
|
|
doc.on('movestart', function(e) {
|
|
|
|
// If the movestart is heading off in an upwards or downwards
|
|
// direction, prevent it so that the browser scrolls normally.
|
|
|
|
if ((e.distX > e.distY && e.distX < -e.distY) ||
|
|
(e.distX < e.distY && e.distX > -e.distY)) {
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
|
|
doc.bind('swipeleft', 'ul[data-clearing] li', function () {
|
|
var clearing = $('.clearing-blackout').find('ul[data-clearing]');
|
|
methods.go(clearing, 'next');
|
|
});
|
|
|
|
doc.bind('swiperight', 'ul[data-clearing] li', function () {
|
|
var clearing = $('.clearing-blackout').find('ul[data-clearing]');
|
|
methods.go(clearing, 'prev');
|
|
});
|
|
|
|
defaults.initialized = true;
|
|
},
|
|
|
|
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 (!methods.locked()) {
|
|
|
|
// set the image to the selected thumbnail
|
|
image.attr('src', this.load($image));
|
|
|
|
image.is_good(function () {
|
|
// toggle the gallery if not visible
|
|
root.addClass('clearing-blackout');
|
|
container.addClass('clearing-container');
|
|
methods.caption(visible_image.find('.clearing-caption'), $image);
|
|
visible_image.show();
|
|
methods.fix_height(target);
|
|
|
|
methods.center(image);
|
|
|
|
// shift the thumbnails if necessary
|
|
methods.shift(current, target, function () {
|
|
target.siblings().removeClass('visible');
|
|
target.addClass('visible');
|
|
});
|
|
});
|
|
}
|
|
},
|
|
|
|
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');
|
|
}
|
|
});
|
|
lis.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');
|
|
|
|
// preload next and previous
|
|
this.preload($image);
|
|
|
|
if (href) {
|
|
return href;
|
|
}
|
|
|
|
return $image.attr('src');
|
|
},
|
|
|
|
preload : function ($image) {
|
|
var next = $image.closest('li').next(),
|
|
prev = $image.closest('li').prev(),
|
|
next_a, prev_a,
|
|
next_img, prev_img;
|
|
|
|
if (next.length > 0) {
|
|
next_img = new Image();
|
|
next_a = next.find('a');
|
|
if (next_a.length > 0) {
|
|
next_img.src = next_a.attr('href');
|
|
} else {
|
|
next_img.src = next.find('img').attr('src');
|
|
}
|
|
}
|
|
|
|
if (prev.length > 0) {
|
|
prev_img = new Image();
|
|
prev_a = prev.find('a');
|
|
if (prev_a.length > 0) {
|
|
prev_img.src = prev_a.attr('href');
|
|
} else {
|
|
prev_img.src = prev.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(),
|
|
container = clearing.closest('.clearing-container'),
|
|
target_offset = target.position().left,
|
|
thumbs_offset = clearing.position().left,
|
|
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)) {
|
|
methods.lock();
|
|
clearing.animate({left : left + width}, 300, methods.unlock);
|
|
} else if (/right/.test(direction)) {
|
|
methods.lock();
|
|
clearing.animate({left : left - width}, 300, methods.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;
|
|
methods.lock();
|
|
|
|
if (skip_shift > 0) {
|
|
clearing.animate({left : -(skip_shift * width)}, 300, methods.unlock);
|
|
} else {
|
|
clearing.animate({left : 0}, 300, methods.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),
|
|
container = $('.clearing-container'),
|
|
up_count = Math.floor(container.outerWidth() / li_width) - 1,
|
|
shift_count = lis.length - up_count,
|
|
target_index = lis.index(target),
|
|
current_index = lis.index(current),
|
|
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) {
|
|
if (target_index - 1 === current_index) {
|
|
return true;
|
|
} else if (target_index + 1 === current_index) {
|
|
return true;
|
|
} else if (target_index === 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);
|
|
},
|
|
|
|
// experimental functionality for overwriting or extending
|
|
// clearing methods during initialization.
|
|
//
|
|
// ex $doc.foundationClearing({}, {
|
|
// shift : function (current, target, callback) {
|
|
// // modify arguments, etc.
|
|
// this._super('shift', [current, target, callback]);
|
|
// // do something else here.
|
|
// }
|
|
// });
|
|
|
|
extend : function (supers, extendMethods) {
|
|
$.each(supers, function (name, method) {
|
|
if (extendMethods.hasOwnProperty(name)) {
|
|
superMethods[name] = method;
|
|
}
|
|
});
|
|
|
|
$.extend(methods, extendMethods);
|
|
},
|
|
|
|
// you can call this._super('methodName', [args]) to call
|
|
// the original method and wrap it in your own code
|
|
|
|
_super : function (method, args) {
|
|
return superMethods[method].apply(this, args);
|
|
}
|
|
};
|
|
|
|
$.fn.foundationClearing = function (method) {
|
|
if (methods[method]) {
|
|
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
|
} else if (typeof method === 'object' || !method) {
|
|
return methods.init.apply(this, arguments);
|
|
} else {
|
|
$.error('Method ' + method + ' does not exist on jQuery.foundationClearing');
|
|
}
|
|
};
|
|
|
|
// jquery.imageready.js
|
|
// @weblinc, @jsantell, (c) 2012
|
|
|
|
(function( $ ) {
|
|
$.fn.is_good = function ( callback, userSettings ) {
|
|
var
|
|
options = $.extend( {}, $.fn.is_good.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.is_good.defaults = {
|
|
cachePrefix: 'random'
|
|
};
|
|
|
|
}(jQuery));
|
|
|
|
}(jQuery, this));
|