920 lines
27 KiB
JavaScript
920 lines
27 KiB
JavaScript
/*!
|
|
* Infinite Ajax Scroll, a jQuery plugin
|
|
* Version 1.0.2
|
|
* https://github.com/webcreate/infinite-ajax-scroll
|
|
*
|
|
* Copyright (c) 2011-2013 Jeroen Fiege
|
|
* Licensed under MIT:
|
|
* https://raw.github.com/webcreate/infinite-ajax-scroll/master/MIT-LICENSE.txt
|
|
*/
|
|
|
|
(function ($) {
|
|
|
|
'use strict';
|
|
|
|
Date.now = Date.now || function () { return +new Date(); };
|
|
|
|
$.ias = function (options)
|
|
{
|
|
// setup
|
|
var opts = $.extend({}, $.ias.defaults, options);
|
|
var util = new $.ias.util(); // utilities module
|
|
var paging = new $.ias.paging(opts.scrollContainer); // paging module
|
|
var hist = (opts.history ? new $.ias.history() : false); // history module
|
|
var _self = this;
|
|
|
|
// Mellow : Sent from module to handle layered navigation
|
|
var Layered = (opts.LayeredNavCat ? new $.ias.LayeredNavCat() : false);
|
|
|
|
// Mellow : Get initial number of pages (in text format)
|
|
var maxpage = $('#pagination_nbpages:first').text();
|
|
if (maxpage.length)
|
|
var EndPageNum = ' / ' + maxpage;
|
|
else
|
|
var EndPageNum = '';
|
|
|
|
// Mellow : need global functions to call from layered navigation module
|
|
$.ias_hidepage = function() {
|
|
hide_pagination();
|
|
};
|
|
$.ias_reset = function() {
|
|
remove_loader();
|
|
$(opts.container).removeClass('isscrolling');
|
|
opts.scrollContainer.scroll(scroll_handler);
|
|
};
|
|
$.ias_init_pages = function() {
|
|
var maxpage = $('#pagination_nbpages:first').text();
|
|
if (maxpage.length)
|
|
EndPageNum = ' / ' + maxpage;
|
|
else
|
|
EndPageNum = '';
|
|
paging.splicePages();
|
|
};
|
|
$.ias_stop_scroll = function() {
|
|
opts.scrollContainer.unbind('scroll', scroll_handler);
|
|
};
|
|
$.ias.renderComplete = opts.onRenderComplete;
|
|
|
|
|
|
/**
|
|
* Initialize
|
|
*
|
|
* - tracks scrolling through pages
|
|
* - remembers current page with the history module
|
|
* - setup scroll event and hides pagination element
|
|
* - loads and scrolls to previous page when we have something in our history
|
|
*
|
|
* @return self
|
|
*/
|
|
function init()
|
|
{
|
|
var pageNum;
|
|
|
|
// track page number changes
|
|
paging.onChangePage(function (pageNum, scrollOffset, pageUrl) {
|
|
if (hist) {
|
|
hist.setPage(pageNum, pageUrl);
|
|
}
|
|
|
|
// call onPageChange event
|
|
opts.onPageChange.call(this, pageNum, pageUrl, scrollOffset);
|
|
});
|
|
|
|
// setup scroll and hide pagination
|
|
reset();
|
|
|
|
// Mellow : Don't load previous page if layered nav, but scroll to top and remove hash
|
|
if (Layered && Layered.State == true) {
|
|
$('html,body').scrollTop(0);
|
|
//util.forceScrollTop(0);
|
|
if (window.location.hash.substring(0, 7) == "#/page-")
|
|
window.location.replace(('' + window.location).split('#')[0] + '');
|
|
else if (window.location.href.split('/page-').length == 2 && window.location.href.split('/page-')[1] != '')
|
|
window.location.replace(('' + window.location).split('/page-')[0] + '');
|
|
}
|
|
else {
|
|
// load and scroll to previous page
|
|
if (hist && hist.havePage()) {
|
|
stop_scroll();
|
|
|
|
pageNum = hist.getPage();
|
|
|
|
util.forceScrollTop(function () {
|
|
var curThreshold;
|
|
|
|
if (pageNum > 1) {
|
|
paginateToPage(pageNum);
|
|
|
|
curThreshold = get_scroll_threshold(true);
|
|
$('html, body').scrollTop(curThreshold);
|
|
}
|
|
else {
|
|
reset();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
return _self;
|
|
}
|
|
|
|
// initialize
|
|
init();
|
|
|
|
/**
|
|
* Reset scrolling and hide pagination links
|
|
*
|
|
* @return void
|
|
*/
|
|
function reset()
|
|
{
|
|
hide_pagination();
|
|
|
|
opts.scrollContainer.scroll(scroll_handler);
|
|
}
|
|
|
|
/**
|
|
* Scroll event handler
|
|
*
|
|
* @return void
|
|
*/
|
|
function scroll_handler()
|
|
{
|
|
var curScrOffset,
|
|
scrThreshold;
|
|
|
|
// Mellow : Avoid paginating if there is another ajax query running (blocklayered)
|
|
if($.ajaxRunning) return;
|
|
|
|
curScrOffset = util.getCurrentScrollOffset(opts.scrollContainer);
|
|
scrThreshold = get_scroll_threshold();
|
|
|
|
if (curScrOffset >= scrThreshold) {
|
|
if (get_current_page() >= opts.triggerPageThreshold) {
|
|
stop_scroll();
|
|
show_trigger(function () {
|
|
paginate(curScrOffset);
|
|
});
|
|
}
|
|
else {
|
|
paginate(curScrOffset);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Cancel scrolling
|
|
*
|
|
* @return void
|
|
*/
|
|
function stop_scroll()
|
|
{
|
|
opts.scrollContainer.unbind('scroll', scroll_handler);
|
|
|
|
// Mellow : Better way to treat noneleft display
|
|
var urlNextPage;
|
|
urlNextPage = $(opts.next).attr('href');
|
|
if (!urlNextPage) {
|
|
if (opts.noneleft && !$('.ias_none_left').length) {
|
|
if (opts.noneleftlink)
|
|
$(opts.container).find(opts.item).last().after("<div class='ias_none_left'><a href='#' title='Top'>"+opts.noneleft+"</a>");
|
|
else
|
|
$(opts.container).find(opts.item).last().after("<div class='ias_none_left'><span>"+opts.noneleft+"</span>");
|
|
$('.ias_none_left a').click(function(){
|
|
$('html, body').animate({'scrollTop':0}, 'medium', 'swing');
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Hide pagination
|
|
*
|
|
* @return void
|
|
*/
|
|
function hide_pagination()
|
|
{
|
|
// Mellow : Remove all but one #pagination elements and hide the one left (when there is more than one)
|
|
var pagination_element = "[id="+opts.pagination.substring(1)+"]";
|
|
var pagination_element_bottom = "[id="+opts.pagination.substring(1)+'_bottom'+"]";
|
|
if ($(pagination_element).length > 1) {
|
|
$(pagination_element).each(function(){
|
|
$(this).hide();
|
|
});
|
|
$(pagination_element).not(':last').remove();
|
|
$(pagination_element_bottom).remove();
|
|
}
|
|
else if ($(pagination_element).length == 1) {
|
|
$(opts.pagination).hide();
|
|
$(pagination_element_bottom).remove();
|
|
}
|
|
else
|
|
$(pagination_element_bottom).hide();
|
|
|
|
}
|
|
|
|
/**
|
|
* Get scroll threshold based on the last item element
|
|
*
|
|
* @param boolean pure indicates if the thresholdMargin should be applied
|
|
* @return integer threshold
|
|
*/
|
|
function get_scroll_threshold(pure)
|
|
{
|
|
var el,
|
|
threshold;
|
|
|
|
el = $(opts.container).find(opts.item).last();
|
|
|
|
if (el.size() === 0) {
|
|
return 0;
|
|
}
|
|
|
|
threshold = el.offset().top + el.height();
|
|
|
|
if (!pure) {
|
|
threshold += opts.thresholdMargin;
|
|
}
|
|
|
|
return threshold;
|
|
}
|
|
|
|
/**
|
|
* Load the items from the next page.
|
|
*
|
|
* @param int curScrOffset current scroll offset
|
|
* @param function onCompleteHandler callback function
|
|
* @return void
|
|
*/
|
|
function paginate(curScrOffset, onCompleteHandler)
|
|
{
|
|
var urlNextPage;
|
|
urlNextPage = $(opts.next).attr('href');
|
|
if (!urlNextPage) {
|
|
if (opts.noneleft && !$('.ias_none_left').length) {
|
|
if (opts.noneleftlink)
|
|
$(opts.container).find(opts.item).last().after("<div class='ias_none_left'><a href='#' title='Top'>"+opts.noneleft+"</a>");
|
|
else
|
|
$(opts.container).find(opts.item).last().after("<div class='ias_none_left'><span>"+opts.noneleft+"</span>");
|
|
$('.ias_none_left a').click(function(){
|
|
$('html, body').animate({'scrollTop':0}, 'medium', 'swing');
|
|
});
|
|
}
|
|
return stop_scroll();
|
|
}
|
|
|
|
if (opts.beforePageChange && $.isFunction(opts.beforePageChange)) {
|
|
if (opts.beforePageChange(curScrOffset, urlNextPage) === false) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
paging.pushPages(curScrOffset, urlNextPage);
|
|
|
|
stop_scroll();
|
|
show_loader(urlNextPage);
|
|
|
|
// Mellow : If layared nav is on, we click the next button. blocklayered will do the rest!
|
|
if (Layered && Layered.State == true) {
|
|
$(opts.container).addClass('isscrolling');
|
|
if (opts.history == false) $(opts.container).addClass('nohashes');
|
|
$(opts.next).trigger('click');
|
|
return;
|
|
}
|
|
|
|
loadItems(urlNextPage, function (data, items) {
|
|
// call the onLoadItems callback
|
|
var result = opts.onLoadItems.call(this, items),
|
|
curLastItem;
|
|
|
|
if (result !== false) {
|
|
$(items).hide(); // at first, hide it so we can fade it in later
|
|
|
|
// insert them after the last item with a nice fadeIn effect
|
|
curLastItem = $(opts.container).find(opts.item).last();
|
|
curLastItem.after(items);
|
|
$(items).fadeIn();
|
|
}
|
|
|
|
urlNextPage = $(opts.next, data).attr('href');
|
|
|
|
// update pagination
|
|
// Mellow : Modified to replace all pagination elements
|
|
var pagination_element = "[id="+opts.pagination.substring(1)+"]";
|
|
$(pagination_element).each(function(){
|
|
$(this).replaceWith($(opts.pagination, data));
|
|
});
|
|
|
|
remove_loader();
|
|
hide_pagination();
|
|
|
|
if (urlNextPage) {
|
|
reset();
|
|
}
|
|
else {
|
|
stop_scroll();
|
|
}
|
|
|
|
// call the onRenderComplete callback
|
|
opts.onRenderComplete.call(this, items);
|
|
|
|
if (onCompleteHandler) {
|
|
onCompleteHandler.call(this);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Loads items from certain url, triggers
|
|
* onComplete handler when finished
|
|
*
|
|
* @param string the url to load
|
|
* @param function the callback function
|
|
* @param int minimal time the loading should take, defaults to $.ias.default.loaderDelay
|
|
* @return void
|
|
*/
|
|
function loadItems(url, onCompleteHandler, delay)
|
|
{
|
|
var items = [],
|
|
container,
|
|
startTime = Date.now(),
|
|
diffTime,
|
|
self;
|
|
|
|
delay = delay || opts.loaderDelay;
|
|
|
|
$.get(url, null, function (data) {
|
|
// walk through the items on the next page
|
|
// and add them to the items array
|
|
container = $(opts.container, data).eq(0);
|
|
if (0 === container.length) {
|
|
// incase the element is a root element (body > element),
|
|
// try to filter it
|
|
container = $(data).filter(opts.container).eq(0);
|
|
}
|
|
|
|
if (container) {
|
|
container.find(opts.item).each(function () {
|
|
items.push(this);
|
|
});
|
|
}
|
|
|
|
if (onCompleteHandler) {
|
|
self = this;
|
|
diffTime = Date.now() - startTime;
|
|
if (diffTime < delay) {
|
|
setTimeout(function () {
|
|
onCompleteHandler.call(self, data, items);
|
|
}, delay - diffTime);
|
|
} else {
|
|
onCompleteHandler.call(self, data, items);
|
|
}
|
|
}
|
|
}, 'html');
|
|
}
|
|
|
|
/**
|
|
* Paginate to a certain page number.
|
|
*
|
|
* - keeps paginating till the pageNum is reached
|
|
*
|
|
* @return void
|
|
*/
|
|
function paginateToPage(pageNum)
|
|
{
|
|
var curThreshold = get_scroll_threshold(true);
|
|
|
|
if (curThreshold > 0) {
|
|
paginate(curThreshold, function () {
|
|
stop_scroll();
|
|
|
|
if ((paging.getCurPageNum(curThreshold) + 1) < pageNum) {
|
|
paginateToPage(pageNum);
|
|
|
|
$('html,body').animate({'scrollTop': curThreshold}, 400, 'swing');
|
|
}
|
|
else {
|
|
$('html,body').animate({'scrollTop': curThreshold}, 1000, 'swing');
|
|
|
|
reset();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function get_current_page()
|
|
{
|
|
var curScrOffset = util.getCurrentScrollOffset(opts.scrollContainer);
|
|
|
|
return paging.getCurPageNum(curScrOffset);
|
|
}
|
|
|
|
/**
|
|
* Return the active loader or creates a new loader
|
|
*
|
|
* @return object loader jquery object
|
|
*/
|
|
function get_loader()
|
|
{
|
|
var loader = $('.ias_loader');
|
|
|
|
if (loader.size() === 0) {
|
|
if (opts.loader && opts.loadingtext) {
|
|
loader = $("<div class='ias_loader'><div class='ias_load_img'>"+opts.loader+"</div><span class='ias_load_txt'>"+opts.loadingtext+"</span></div>");
|
|
} else if (opts.loader) {
|
|
loader = $("<div class='ias_loader'><div class='ias_load_img'>"+opts.loader+"</div></div>");
|
|
} else if (opts.loadingtext) {
|
|
loader = $("<div class='ias_loader'><span class='ias_load_txt'>"+opts.loadingtext+"</span></div>");
|
|
}
|
|
loader.hide();
|
|
}
|
|
return loader;
|
|
}
|
|
|
|
/**
|
|
* Inserts the loader and does a fadeIn.
|
|
* Inserts also an interpage to display page num / total
|
|
* @return void
|
|
*/
|
|
function show_loader(urlNextPage)
|
|
{
|
|
var loader = get_loader(),
|
|
el;
|
|
|
|
// Mellow : Get next page num (from urlNextPage string)
|
|
if (Layered && Layered.State == true) {
|
|
var NextPage = urlNextPage.split('page-')[urlNextPage.split('page-').length-1];
|
|
// correct little bug with blocklayered strange urls...
|
|
if ( NextPage == '1') NextPage = '2';
|
|
}
|
|
else {
|
|
if (urlNextPage.split('?p=').length > 1)
|
|
var NextPage = urlNextPage.split('?p=')[1];
|
|
else
|
|
var NextPage = urlNextPage.split('&p=')[1];
|
|
}
|
|
|
|
// Generate interpage (class ajax_block_product is requied! Adjust css of #ias_interpage in /css/jquery.ias.css)
|
|
var interpage = $('<li id="ias_interpage" class="ajax_block_product" style="display:none"><span>Page ' + NextPage + EndPageNum + '</span></li>');
|
|
|
|
if (opts.customLoaderProc !== false) {
|
|
opts.customLoaderProc(loader);
|
|
} else {
|
|
el = $(opts.container).find(opts.item).last();
|
|
//el.after(interpage, loader);
|
|
loader.fadeIn();
|
|
}
|
|
|
|
// Mellow : Show interpage only when loader is removed (a plugin for special event 'destroyed' is added at the end of this file)
|
|
// If you want to show interpage and loader at the same time, change css of #ias_interpage to 'display:block'
|
|
$(loader).bind('destroyed', function() {
|
|
//interpage.fadeIn();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Removes the loader.
|
|
*
|
|
* return void
|
|
*/
|
|
function remove_loader()
|
|
{
|
|
var loader = get_loader();
|
|
loader.remove();
|
|
}
|
|
|
|
/**
|
|
* Return the active trigger or creates a new trigger
|
|
*
|
|
* @return object trigger jquery object
|
|
*/
|
|
function get_trigger(callback)
|
|
{
|
|
var trigger = $('.ias_trigger');
|
|
|
|
if (trigger.size() === 0) {
|
|
trigger = $('<div class="ias_trigger"><a href="#">' + opts.trigger + '</a></div>');
|
|
trigger.hide();
|
|
}
|
|
|
|
$('a', trigger)
|
|
.unbind('click')
|
|
.bind('click', function () { remove_trigger(); callback.call(); return false; })
|
|
;
|
|
|
|
return trigger;
|
|
}
|
|
|
|
/**
|
|
* @param function callback of the trigger (get's called onClick)
|
|
*/
|
|
function show_trigger(callback)
|
|
{
|
|
// Mellow : Avoid showing 'load more' when there is not more
|
|
var urlNextPage;
|
|
urlNextPage = $(opts.next).attr('href');
|
|
if (urlNextPage) {
|
|
var trigger = get_trigger(callback),
|
|
el;
|
|
el = $(opts.container).find(opts.item).last();
|
|
el.after(trigger);
|
|
trigger.fadeIn();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes the trigger.
|
|
*
|
|
* return void
|
|
*/
|
|
function remove_trigger()
|
|
{
|
|
var trigger = get_trigger();
|
|
|
|
trigger.remove();
|
|
}
|
|
};
|
|
|
|
// plugin defaults
|
|
$.ias.defaults = {
|
|
container: '#container',
|
|
scrollContainer: $(window),
|
|
item: '.item',
|
|
pagination: '#pagination',
|
|
next: '.next',
|
|
noneleft: false,
|
|
loader: '<img src="images/loader.gif"/>',
|
|
loaderDelay: 600,
|
|
triggerPageThreshold: 3,
|
|
trigger: 'Load more items',
|
|
thresholdMargin: 0,
|
|
history : true,
|
|
onPageChange: function () {},
|
|
beforePageChange: function () {},
|
|
onLoadItems: function () {},
|
|
onRenderComplete: function () {},
|
|
customLoaderProc: false
|
|
};
|
|
|
|
// utility module
|
|
$.ias.util = function ()
|
|
{
|
|
// setup
|
|
var wndIsLoaded = false;
|
|
var forceScrollTopIsCompleted = false;
|
|
var self = this;
|
|
|
|
/**
|
|
* Initialize
|
|
*
|
|
* @return void
|
|
*/
|
|
function init()
|
|
{
|
|
$(window).load(function () {
|
|
wndIsLoaded = true;
|
|
});
|
|
}
|
|
|
|
// initialize
|
|
init();
|
|
|
|
/**
|
|
* Force browsers to scroll to top.
|
|
*
|
|
* - When you hit back in you browser, it automatically scrolls
|
|
* back to the last position. There is no way to stop this
|
|
* in a nice way, so this function does it the hard way.
|
|
*
|
|
* @param function onComplete callback function
|
|
* @return void
|
|
*/
|
|
this.forceScrollTop = function (onCompleteHandler)
|
|
{
|
|
$('html,body').scrollTop(0);
|
|
|
|
if (!forceScrollTopIsCompleted) {
|
|
if (!wndIsLoaded) {
|
|
setTimeout(function () {self.forceScrollTop(onCompleteHandler); }, 1);
|
|
} else {
|
|
onCompleteHandler.call();
|
|
forceScrollTopIsCompleted = true;
|
|
}
|
|
}
|
|
};
|
|
|
|
this.getCurrentScrollOffset = function (container)
|
|
{
|
|
var scrTop,
|
|
wndHeight;
|
|
|
|
// the way we calculate if we have to load the next page depends on which container we have
|
|
if (container.get(0) === window) {
|
|
scrTop = container.scrollTop();
|
|
} else {
|
|
scrTop = container.offset().top;
|
|
}
|
|
|
|
wndHeight = container.height();
|
|
|
|
return scrTop + wndHeight;
|
|
};
|
|
};
|
|
|
|
// paging module
|
|
$.ias.paging = function ()
|
|
{
|
|
// setup
|
|
var pagebreaks = [[0, document.location.toString()]];
|
|
var changePageHandler = function () {};
|
|
var lastPageNum = 1;
|
|
var util = new $.ias.util();
|
|
|
|
/**
|
|
* Initialize
|
|
*
|
|
* @return void
|
|
*/
|
|
function init()
|
|
{
|
|
$(window).scroll(scroll_handler);
|
|
}
|
|
|
|
// initialize
|
|
init();
|
|
|
|
/**
|
|
* Scroll handler
|
|
*
|
|
* - Triggers changePage event
|
|
*
|
|
* @return void
|
|
*/
|
|
function scroll_handler()
|
|
{
|
|
var curScrOffset,
|
|
curPageNum,
|
|
curPagebreak,
|
|
scrOffset,
|
|
urlPage;
|
|
|
|
curScrOffset = util.getCurrentScrollOffset($(window));
|
|
|
|
curPageNum = getCurPageNum(curScrOffset);
|
|
curPagebreak = getCurPagebreak(curScrOffset);
|
|
|
|
if (lastPageNum !== curPageNum) {
|
|
scrOffset = curPagebreak[0];
|
|
urlPage = curPagebreak[1];
|
|
changePageHandler.call({}, curPageNum, scrOffset, urlPage); // @todo fix for window height
|
|
}
|
|
|
|
lastPageNum = curPageNum;
|
|
}
|
|
|
|
/**
|
|
* Returns current page number based on scroll offset
|
|
*
|
|
* @param int scroll offset
|
|
* @return int current page number
|
|
*/
|
|
function getCurPageNum(scrollOffset)
|
|
{
|
|
for (var i = (pagebreaks.length - 1); i > 0; i--) {
|
|
if (scrollOffset > pagebreaks[i][0]) {
|
|
return i + 1;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Public function for getCurPageNum
|
|
*
|
|
* @param int scrollOffset defaulst to the current
|
|
* @return int current page number
|
|
*/
|
|
this.getCurPageNum = function (scrollOffset)
|
|
{
|
|
scrollOffset = scrollOffset || util.getCurrentScrollOffset($(window));
|
|
|
|
return getCurPageNum(scrollOffset);
|
|
};
|
|
|
|
/**
|
|
* Returns current pagebreak information based on scroll offset
|
|
*
|
|
* @param int scroll offset
|
|
* @return array pagebreak information
|
|
*/
|
|
function getCurPagebreak(scrollOffset)
|
|
{
|
|
for (var i = (pagebreaks.length - 1); i >= 0; i--) {
|
|
if (scrollOffset > pagebreaks[i][0]) {
|
|
return pagebreaks[i];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Sets onchangePage event handler
|
|
*
|
|
* @param function event handler
|
|
* @return void
|
|
*/
|
|
this.onChangePage = function (fn)
|
|
{
|
|
changePageHandler = fn;
|
|
};
|
|
|
|
/**
|
|
* pushes the pages tracker
|
|
*
|
|
* @param int scroll offset for the new page
|
|
* @return void
|
|
*/
|
|
this.pushPages = function (scrollOffset, urlNextPage)
|
|
{
|
|
pagebreaks.push([scrollOffset, urlNextPage]);
|
|
};
|
|
|
|
// Mellow
|
|
this.splicePages = function(scrollOffset, urlNextPage)
|
|
{
|
|
pagebreaks.splice(0, 100, [0, document.location.toString()]);
|
|
};
|
|
};
|
|
|
|
// Mellow
|
|
$.ias.LayeredNavCat = function() {
|
|
this.State = true;
|
|
};
|
|
|
|
// history module
|
|
$.ias.history = function ()
|
|
{
|
|
// setup
|
|
var isPushed = false;
|
|
var isHtml5 = false;
|
|
|
|
/**
|
|
* Initialize
|
|
*
|
|
* @return void
|
|
*/
|
|
function init()
|
|
{
|
|
isHtml5 = !!(window.history && history.pushState && history.replaceState);
|
|
isHtml5 = false; // html5 functions disabled due to problems in chrome
|
|
}
|
|
|
|
// initialize
|
|
init();
|
|
|
|
/**
|
|
* Sets page to history
|
|
*
|
|
* @return void;
|
|
*/
|
|
this.setPage = function (pageNum, pageUrl)
|
|
{
|
|
this.updateState({page : pageNum}, '', pageUrl);
|
|
};
|
|
|
|
/**
|
|
* Checks if we have a page set in the history
|
|
*
|
|
* @return bool returns true when we have a previous page, false otherwise
|
|
*/
|
|
this.havePage = function ()
|
|
{
|
|
return (this.getState() !== false);
|
|
};
|
|
|
|
/**
|
|
* Gets the previous page from history
|
|
*
|
|
* @return int page number of previous page
|
|
*/
|
|
this.getPage = function ()
|
|
{
|
|
var stateObj;
|
|
|
|
if (this.havePage()) {
|
|
stateObj = this.getState();
|
|
return stateObj.page;
|
|
}
|
|
return 1;
|
|
};
|
|
|
|
/**
|
|
* Returns current state
|
|
*
|
|
* @return object stateObj
|
|
*/
|
|
this.getState = function ()
|
|
{
|
|
var haveState,
|
|
stateObj,
|
|
pageNum;
|
|
|
|
if (isHtml5) {
|
|
stateObj = history.state;
|
|
if (stateObj && stateObj.ias) {
|
|
return stateObj.ias;
|
|
}
|
|
}
|
|
else {
|
|
haveState = (window.location.hash.substring(0, 7) === '#/page-');
|
|
if (haveState) {
|
|
pageNum = parseInt(window.location.hash.replace('#/page-', ''), 10);
|
|
return { page : pageNum };
|
|
}
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Pushes state when not pushed already, otherwise
|
|
* replaces the state.
|
|
*
|
|
* @param obj stateObj
|
|
* @param string title
|
|
* @param string url
|
|
* @return void
|
|
*/
|
|
this.updateState = function (stateObj, title, url)
|
|
{
|
|
if (isPushed) {
|
|
this.replaceState(stateObj, title, url);
|
|
}
|
|
else {
|
|
this.pushState(stateObj, title, url);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Pushes state to history.
|
|
*
|
|
* @param obj stateObj
|
|
* @param string title
|
|
* @param string url
|
|
* @return void
|
|
*/
|
|
this.pushState = function (stateObj, title, url)
|
|
{
|
|
var hash;
|
|
|
|
if (isHtml5) {
|
|
history.pushState({ ias : stateObj }, title, url);
|
|
}
|
|
else {
|
|
// Mellow treat blocklayered friendly urls
|
|
if (stateObj.page > 0 ) {
|
|
if (window.location.href.split('#').length == 2 && window.location.href.split('#')[1] != '') {
|
|
hash = '#' + window.location.href.split('#')[1].replace(/\/page-(\d+)/, '') + "/page-" + stateObj.page;
|
|
window.location.replace(('' + window.location).split('#')[0] + hash);
|
|
} else {
|
|
hash = "#/page-" + stateObj.page;
|
|
window.location.replace(hash);
|
|
}
|
|
}
|
|
//hash = (stateObj.page > 0 ? '#/page-' + stateObj.page : '');
|
|
//window.location.hash = hash;
|
|
}
|
|
isPushed = true;
|
|
};
|
|
|
|
/**
|
|
* Replaces current history state.
|
|
*
|
|
* @param obj stateObj
|
|
* @param string title
|
|
* @param string url
|
|
* @return void
|
|
*/
|
|
this.replaceState = function (stateObj, title, url)
|
|
{
|
|
if (isHtml5) {
|
|
history.replaceState({ ias : stateObj }, title, url);
|
|
}
|
|
else {
|
|
this.pushState(stateObj, title, url);
|
|
}
|
|
};
|
|
};
|
|
})(jQuery);
|
|
|
|
(function($){
|
|
$.event.special.destroyed = {
|
|
remove: function(o) {
|
|
if (o.handler) {
|
|
o.handler()
|
|
}
|
|
}
|
|
}
|
|
})(jQuery);
|
|
|