friendicablog/view/theme/blogng/javascripts/jquery.foundation.clearing.js

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">&times;</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));