/** * Author: Sergey Kukunin * See: https://github.com/Kukunin/jquery-endless-scroll */ (function($) { 'use strict'; // Is pushState supported by this browser? $.support.pushState = window.history && window.history.pushState && window.history.replaceState && // pushState isn't reliable on iOS until 5. !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/) //Declaration of modules var scrollModule = { init: function(options, obj) { obj.options = $.extend({ scrollContainer: window, scrollPadding: 100, scrollEventDelay: 300 }, options); this.options = obj.options; this.container = obj.container; obj.scrollModule = this; this._toplock = true; this._bottomlock = true; this.scrollContainer = $(this.options.scrollContainer); this.updateEntities(); this.sortMarkers(); this.currentPage = null; this.container.on("jes:afterPageLoad", $.proxy(function(event, url, placement) { this.updateEntities(); this.sortMarkers(); this.checkMarker(); if ( placement == "top" ) { //Get offset between first and second pages var offset = this.markers[1].top, scrollTop = this.scrollContainer.scrollTop(); this.scrollContainer.scrollTop(scrollTop + offset); } }, this)); this.bind(); }, updateEntities: function() { this.entities = $(this.options.entity, this.container); }, sortMarkers: function() { var markers = []; $(".jes-marker", this.container).each(function() { markers.push({ top: $(this).position().top, url: $(this).data("jesUrl") }); }); this.markers = markers; }, //Check, whether user scrolled to another page checkMarker: function() { var newPage = this.markers[0], scrollTop = this.scrollContainer.scrollTop(); //Determine, what is current page for ( var i = 1; i < this.markers.length; i++ ) { if ( scrollTop > this.markers[i].top ) { newPage = this.markers[i]; } else { break; } } if ( newPage.url != this.currentPage ) { this.currentPage = newPage.url; $(this.container).trigger("jes:scrollToPage", newPage.url); } }, bind: function() { this.scrollContainer.on("scroll.jes", $.proxy(function(event) { if ( this._tId ) { return; } this.scrollHandler(event); //Clean up mark this._tId= setTimeout($.proxy(function(){ this._tId = null; },this), this.options.scrollEventDelay); }, this)); }, unbind: function() { $(this.options.scrollContainer).off("scroll.jes"); }, scrollHandler: function(ev) { var $scrollable = this.scrollContainer, $entities = this.entities, $firstEntity = $entities.first(), $lastEntity = $entities.last(); var scrollTop = $scrollable.scrollTop(), height = $scrollable.height(), scrollBottom = scrollTop + height; var topEntityPosition = $firstEntity.position().top, topTarget = topEntityPosition + this.options.scrollPadding, bottomEntityPosition = $lastEntity.outerHeight() + $lastEntity.position().top, bottomTarget = bottomEntityPosition - this.options.scrollPadding; //Don't trigger event again, if already fired //Visitor have to leave the area and get back to fire event again //Process top threshold if ( scrollTop < topTarget ) { if ( !this._toplock ) { $(this.container).trigger("jes:topThreshold"); this._toplock = true; } } else { this._toplock = false; } //Process bottom threshold if ( scrollBottom > bottomTarget ) { if ( !this._bottomlock ) { $(this.container).trigger("jes:bottomThreshold"); this._bottomlock = true; } } else { this._bottomlock = false; } this.checkMarker(); } } var ajaxModule = { init: function(options, obj) { obj.options = $.extend({ }, options); this.options = obj.options; this.container = obj.container; //markers this.setMarker($(this.options.entity, this.container).first(), location.href); obj.ajaxModule = this; }, loadPage: function(url, placement, callback) { //The hash with methods list //depends from placement var actions = { top: { find: 'first', inject: 'insertBefore' }, bottom: { find: 'last', inject: 'insertAfter' } }, action = actions[placement]; this.container.trigger("jes:beforePageLoad", [url, placement]); //Make AJAX query $.get(url, null, $.proxy(function (_data) { var data = $("