1/* 2 -------------------------------- 3 Infinite Scroll 4 -------------------------------- 5 + https://github.com/paulirish/infinitescroll 6 + version 2.0b2.110713 7 + Copyright 2011 Paul Irish & Luke Shumard 8 + Licensed under the MIT license 9 10 + Documentation: http://infinite-scroll.com/ 11 12*/ 13 14(function (window, $, undefined) { 15 16 $.infinitescroll = function infscr(options, callback, element) { 17 18 this.element = $(element); 19 this._create(options, callback); 20 21 }; 22 23 $.infinitescroll.defaults = { 24 loading: { 25 finished: undefined, 26 finishedMsg: "<em>Congratulations, you've reached the end of the internet.</em>", 27 img: "http://www.infinite-scroll.com/loading.gif", 28 msg: null, 29 msgText: "<em>Loading the next set of posts...</em>", 30 selector: null, 31 speed: 'fast', 32 start: undefined, 33 prefix: '', 34 postfix: '' 35 }, 36 state: { 37 isDuringAjax: false, 38 isInvalidPage: false, 39 isDestroyed: false, 40 isDone: false, // For when it goes all the way through the archive. 41 isPaused: false, 42 currPage: 1 43 }, 44 callback: undefined, 45 debug: false, 46 behavior: undefined, 47 binder: $(window), // used to cache the selector 48 nextSelector: "div.navigation a:first", 49 navSelector: "div.navigation", 50 contentSelector: null, // rename to pageFragment 51 extraScrollPx: 150, 52 itemSelector: "div.post", 53 animate: false, 54 pathParse: undefined, 55 pagerName: 'pageID', 56 pager: { 57 isEnabled: true, 58 attrPageIndex: 'page', 59 currentPage: 1, 60 pages: [], 61 appendTo: false, 62 delta: 2 63 }, 64 dataType: 'html', 65 appendCallback: true, 66 bufferPx: 40, 67 errorCallback: function () { }, 68 infid: 0, //Instance ID 69 pixelsFromNavToBottom: undefined, 70 bottomDelta:0, 71 path: undefined 72 }; 73 74 75 $.infinitescroll.prototype = { 76 77 /* 78 ---------------------------- 79 Private methods 80 ---------------------------- 81 */ 82 83 // Bind or unbind from scroll 84 _binding: function infscr_binding(binding) { 85 86 var instance = this, 87 opts = instance.options; 88 89 // if behavior is defined and this function is extended, call that instead of default 90 if (!!opts.behavior && this['_binding_'+opts.behavior] !== undefined) { 91 this['_binding_'+opts.behavior].call(this); 92 return; 93 } 94 95 if (binding !== 'bind' && binding !== 'unbind') { 96 this._debug('Binding value ' + binding + ' not valid') 97 return false; 98 } 99 100 if (binding == 'unbind') { 101 102 (this.options.binder).unbind('smartscroll.infscr.' + instance.options.infid); 103 104 } else { 105 106 (this.options.binder)[binding]('smartscroll.infscr.' + instance.options.infid, function () { 107 instance.scroll(); 108 }); 109 110 jQuery(window).scroll(function() { 111 instance.scroll(); 112 }); 113 }; 114 115 this._debug('Binding', binding); 116 117 }, 118 119 // Fundamental aspects of the plugin are initialized 120 _create: function infscr_create(options, callback) { 121 // If selectors from options aren't valid, return false 122 if (!this._validate(options)) { return false; } 123 124 this.inOptions = jQuery.extend(true, {}, options); 125 this.inCallback = callback; 126 127 // Define options and shorthand 128 var opts = this.options = $.extend(true, {}, $.infinitescroll.defaults, options), 129 // get the relative URL - everything past the domain name. 130 relurl = /(.*?\/\/).*?(\/.*)/, 131 path = $(opts.nextSelector).attr('href'); 132 133 134 // contentSelector is 'page fragment' option for .load() / .ajax() calls 135 opts.contentSelector = opts.contentSelector || this.element; 136 137 // loading.selector - if we want to place the load message in a specific selector, defaulted to the contentSelector 138 opts.loading.selector = opts.loading.selector || opts.contentSelector; 139 140 // if there's not path, return 141 if (!path) { this._debug('Navigation selector not found'); return; } 142 143 // Set the path to be a relative URL from root. 144 opts.path = this._determinepath(path);
145 146 147 this._determinePager(); 148 149 // Define loading.msg 150 opts.loading.msg = $(opts.loading.prefix + '<div id="infscr-loading"><img alt="Loading..." src="' + opts.loading.img + '" /><div>' + opts.loading.msgText + '</div></div>' + opts.loading.postfix); 151 152 // Preload loading.img 153 (new Image()).src = opts.loading.img; 154 155 // determine loading.start actions 156 opts.loading.start = opts.loading.start || function() { 157 158 //$(opts.navSelector).hide(); 159 opts.loading.msg 160 .appendTo(opts.loading.selector) 161 .show(opts.loading.speed, function () { 162 beginAjax(opts); 163 }); 164 }; 165 166 // determine loading.finished actions 167 opts.loading.finished = opts.loading.finished || function() { 168 opts.loading.msg.fadeOut('normal'); 169 }; 170 171 // callback loading 172 opts.callback = function(instance,data) { 173 if (!!opts.behavior && instance['_callback_'+opts.behavior] !== undefined) { 174 instance['_callback_'+opts.behavior].call($(opts.contentSelector)[0], data); 175 } 176 if (callback) { 177 callback.call($(opts.contentSelector)[0], data); 178 } 179 }; 180 181 this._setup(); 182 183 }, 184 185 _determinePager: function infscr_determinePager() { 186 var opts = this.options; 187 188 if (!opts.pager.isEnabled) { 189 return false; 190 } 191 192 opts.pager.pages = []; 193 194 var pages = jQuery(opts.itemSelector); 195 jQuery(pages).each(function (index, pageContainer) { 196 var pageIndex = jQuery(pageContainer).attr("page"); 197 198 if (pageIndex) { 199 var top = jQuery(pageContainer).offset().top; 200 var page = { 201 page: pageIndex, 202 url: opts.path.join(pageIndex), 203 anchor: jQuery(pageContainer).attr("id"), 204 top: top - 50, 205 bottom: top + jQuery(pageContainer).height() 206 }; 207 208 opts.pager.pages.push(page); 209 } 210 }); 211 212 this._debug('Update pager', opts.pager.pages); 213 214 this._displayPager(opts); 215 216 jQuery(this.element).trigger('NEW_PAGE'); 217 218 }, // end _determinePager 219 220 _displayPager: function infscr_displayPager(opts) { 221 if (jQuery(opts.pager.pages).length <= 1) { 222 return false; 223 } 224 225 var pagerItemsContaner = jQuery("<ul>"); 226 227 // Define pager interval and view pages 228 var startIndex = 1; 229 var endIndex = jQuery(opts.pager.pages).length; 230 if ((opts.pager.currentPage - 1) > opts.pager.delta) { 231 startIndex = opts.pager.currentPage - opts.pager.delta; 232 233 var value = opts.pager.pages[0]; 234 var pageContainre = jQuery('<li class="infscr-pager-page-first"><a href="#' + value.anchor + '"><</a></li>"'); 235 jQuery(pagerItemsContaner).append(pageContainre); 236 } 237 238 var lastPageContainer = null; 239 if ((endIndex - opts.pager.currentPage) > opts.pager.delta) { 240 endIndex = opts.pager.currentPage + opts.pager.delta; 241 242 var value = opts.pager.pages[jQuery(opts.pager.pages).length - 1]; 243 lastPageContainer = jQuery('<li class="infscr-pager-page-last"><a href="#' + value.anchor + '">></a></li>"'); 244 } 245 246 var pages = opts.pager.pages.slice(startIndex - 1, endIndex); 247 this._debug('Pager interval', startIndex, endIndex, pages); 248 249 250 jQuery(pages).each(function (index, value) { 251 252 var pageContainre = jQuery('<li class="infscr-pager-page-' + value.page + '"><a href="#' + value.anchor + '">' + value.page + "</a></li>"); 253 if (value.page == opts.pager.currentPage) { 254 jQuery(pageContainre).addClass('infscr-pager-current'); 255 } 256 jQuery(pagerItemsContaner).append(pageContainre); 257 }); 258 259 if (lastPageContainer) { 260 jQuery(pagerItemsContaner).append(lastPageContainer); 261 } 262 263 var pagerConatiner = jQuery('#infscr-pager'); 264 if (jQuery(pagerConatiner).length == 0) { 265 pagerConatiner = jQuery('<div id="infscr-pager"></div>'); 266 jQuery('body').append(pagerConatiner); 267 } 268 269 270 jQuery(pagerConatiner).html(pagerItemsContaner); 271 272 var instance = this; 273 274 if (opts.pager.appendTo) { 275 this._debug('Use pager appendTo'); 276 jQuery(opts.pager.appendTo).html(pagerConatiner); 277 } 278 279 jQuery(window).scroll(function() { 280 var scrollTop = jQuery(window).scrollTop() + 10; 281 282 // 283 jQuery(opts.pager.pages).each(function(index, info) { 284 if (scrollTop >= info.top && info.bottom > scrollTop) { 285 if (opts.pager.currentPage == info.page) { 286 return false; 287 } 288 289 instance._debug('Change current page', info); 290 291 opts.pager.currentPage = parseInt(info.page); 292 instance._displayPager(opts); 293 jQuery(instance.element).trigger('CHANGE_PAGER', [opts.pager]); 294 295 // element 296 /* 297 var currentPageSelector = '.infscr-pager-page-' + opts.pager.currentPage; 298 jQuery(currentPageSelector).removeClass('infscr-pager-current'); 299 300 opts.pager.currentPage = info.page; 301 currentPageSelector = '.infscr-pager-page-' + opts.pager.currentPage; 302 jQuery(currentPageSelector).addClass('infscr-pager-current'); 303 */ 304 return false; 305 } 306 }); 307 308 if (!opts.pager.appendTo) { 309 var contentContainer = jQuery(opts.contentSelector)[0]; 310 var minTop = jQuery(contentContainer).offset().top 311 if (scrollTop < minTop) { 312 scrollTop = minTop; 313 } 314 315 var position = jQuery(contentContainer).position(); 316 var leftPosition = position.left + jQuery(contentContainer).width() - jQuery(pagerConatiner).width(); 317 318 jQuery(pagerConatiner).css('top', scrollTop); 319 jQuery(pagerConatiner).css('left', leftPosition); 320 } 321 }); 322 }, 323 324 // Console log wrapper 325 _debug: function infscr_debug() { 326 327 if (this.options.debug) { 328 //return window.console && console.log.call(console, arguments); 329 return console.log(arguments); 330 } 331 332 }, 333 334 // find the number to increment in the path. 335 _determinepath: function infscr_determinepath(path) { 336 337 var opts = this.options; 338 339 // if behavior is defined and this function is extended, call that instead of default 340 if (!!opts.behavior && this['_determinepath_'+opts.behavior] !== undefined) { 341 this['_determinepath_'+opts.behavior].call(this,path); 342 return; 343 } 344 345 if (!!opts.pathParse) { 346 this._debug('pathParse manual'); 347 return opts.pathParse; 348 } else { 349 var _regex = new RegExp( opts.pagerName + "=(\\d+)"); 350 var pageNumber = path.match(_regex); 351 if (pageNumber) { 352 opts.state.currPage = parseInt(pageNumber[1]); 353 if (opts.state.currPage > 1) { 354 opts.state.currPage--; 355 } 356 this._debug('Current page', opts.state.currPage); 357 358 var _regexPath = new RegExp( "^(.*?" + opts.pagerName + "=)\\d+(.*?)$"); 359 path = path.match(_regexPath).slice(1); 360 return path; 361 } else { 362 this._debug('Sorry, we couldn\'t parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.'); 363 // Get rid of isInvalidPage to allow permalink to state 364 opts.state.isInvalidPage = true; //prevent it from running on this page. 365 } 366 } 367 368 this._debug('determinePath', path); 369 return path; 370 371 }, 372 373 // Custom error 374 _error: function infscr_error(xhr) { 375 376 var opts = this.options; 377 378 // if behavior is defined and this function is extended, call that instead of default 379 if (!!opts.behavior && this['_error_'+opts.behavior] !== undefined) { 380 this['_error_'+opts.behavior].call(this,xhr); 381 return; 382 } 383 384 if (xhr !== 'destroy' && xhr !== 'end') { 385 xhr = 'unknown'; 386 } 387 388 this._debug('Error', xhr); 389 390 if (xhr == 'end') { 391 this._showdonemsg(); 392 } 393 394 opts.state.isDone = true; 395 opts.state.currPage = 1; // if you need to go back to this instance
396 opts.state.isPaused = false; 397 this._binding('unbind'); 398 399 }, 400 401 // Load Callback 402 _loadcallback: function infscr_loadcallback(box, data) { 403 404 var opts = this.options, 405 callback = this.options.callback, // GLOBAL OBJECT FOR CALLBACK 406 result = (opts.state.isDone) ? 'done' : (!opts.appendCallback) ? 'no-append' : 'append', 407 frag; 408 409 // if behavior is defined and this function is extended, call that instead of default 410 if (!!opts.behavior && this['_loadcallback_'+opts.behavior] !== undefined) { 411 this['_loadcallback_'+opts.behavior].call(this,box,data); 412 return; 413 } 414 415 switch (result) { 416 417 case 'done': 418 419 this._showdonemsg(); 420 return false; 421 422 break; 423 424 case 'no-append': 425 426 if (opts.dataType == 'html') { 427 data = '<div>' + data + '</div>'; 428 data = $(data).find(opts.itemSelector); 429 }; 430 431 break; 432 433 case 'append': 434 435 var children = box.children(); 436 437 // if it didn't return anything 438 if (children.length == 0) { 439 return this._error('end'); 440 } 441 442 443 // use a documentFragment because it works when content is going into a table or UL 444 frag = document.createDocumentFragment(); 445 while (box[0].firstChild) { 446 frag.appendChild(box[0].firstChild); 447 } 448 449 this._debug('contentSelector', $(opts.contentSelector)[0]) 450 $(opts.contentSelector)[0].appendChild(frag); 451 // previously, we would pass in the new DOM element as context for the callback 452 // however we're now using a documentfragment, which doesnt havent parents or children, 453 // so the context is the contentContainer guy, and we pass in an array 454 // of the elements collected as the first argument. 455 456 data = children.get(); 457 458 459 break; 460 461 } 462 463 this._determinePager(); 464 465 // loadingEnd function 466 opts.loading.finished.call($(opts.contentSelector)[0],opts) 467 468 469 // smooth scroll to ease in the new content 470 if (opts.animate) { 471 var scrollTo = $(window).scrollTop() + $('#infscr-loading').height() + opts.extraScrollPx + 'px'; 472 $('html,body').animate({ scrollTop: scrollTo }, 800, function () { opts.state.isDuringAjax = false; }); 473 } 474 475 if (!opts.animate) opts.state.isDuringAjax = false; // once the call is done, we can allow it again. 476 477 callback(this,data); 478 479 }, 480 481 _nearbottom: function infscr_nearbottom() { 482 483 var opts = this.options, 484 pixelsFromWindowBottomToBottom = 0 + $(document).height() - (opts.binder.scrollTop()) - $(window).height(); 485 486 // if behavior is defined and this function is extended, call that instead of default 487 if (!!opts.behavior && this['_nearbottom_'+opts.behavior] !== undefined) { 488 this['_nearbottom_'+opts.behavior].call(this); 489 return; 490 } 491 492 this._debug('math:', pixelsFromWindowBottomToBottom, opts.pixelsFromNavToBottom); 493 494 // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom.... 495 return (pixelsFromWindowBottomToBottom - opts.bufferPx < opts.pixelsFromNavToBottom); 496 497 }, 498 499 // Pause / temporarily disable plugin from firing 500 _pausing: function infscr_pausing(pause) { 501 502 var opts = this.options; 503 504 // if behavior is defined and this function is extended, call that instead of default 505 if (!!opts.behavior && this['_pausing_'+opts.behavior] !== undefined) { 506 this['_pausing_'+opts.behavior].call(this,pause); 507 return; 508 } 509 510 // If pause is not 'pause' or 'resume', toggle it's value 511 if (pause !== 'pause' && pause !== 'resume' && pause !== null) { 512 this._debug('Invalid argument. Toggling pause value instead'); 513 }; 514 515 pause = (pause && (pause == 'pause' || pause == 'resume')) ? pause : 'toggle'; 516 517 switch (pause) { 518 case 'pause':
519 opts.state.isPaused = true; 520 break; 521 522 case 'resume': 523 opts.state.isPaused = false; 524 break; 525 526 case 'toggle': 527 opts.state.isPaused = !opts.state.isPaused; 528 break; 529 } 530 531 this._debug('Paused', opts.state.isPaused); 532 return false; 533 534 }, 535 536 // Behavior is determined 537 // If the behavior option is undefined, it will set to default and bind to scroll 538 _setup: function infscr_setup() { 539 540 var opts = this.options; 541 542 // if behavior is defined and this function is extended, call that instead of default 543 if (!!opts.behavior && this['_setup_'+opts.behavior] !== undefined) { 544 this['_setup_'+opts.behavior].call(this); 545 return; 546 } 547 548 this._binding('bind'); 549 550 return false; 551 552 }, 553 554 // Show done message 555 _showdonemsg: function infscr_showdonemsg() { 556 557 var opts = this.options; 558 559 // if behavior is defined and this function is extended, call that instead of default 560 if (!!opts.behavior && this['_showdonemsg_'+opts.behavior] !== undefined) { 561 this['_showdonemsg_'+opts.behavior].call(this); 562 return; 563 } 564 565 opts.loading.msg 566 .find('img') 567 .hide() 568 .parent() 569 .find('div').html(opts.loading.finishedMsg).animate({ opacity: 1 }, 2000, function () { 570 $(this).parent().fadeOut('normal'); 571 }); 572 573 // user provided callback when done 574 opts.errorCallback.call($(opts.contentSelector)[0],'done'); 575 576 }, 577 578 // grab each selector option and see if any fail 579 _validate: function infscr_validate(opts) { 580 581 for (var key in opts) { 582 if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0) { 583 this._debug('Your ' + key + ' found no elements.'); 584 return false; 585 } 586 return true; 587 } 588 589 }, 590 591 /* 592 ---------------------------- 593 Public methods 594 ---------------------------- 595 */ 596 597 reinit: function infscr_reinit() { 598 this._debug('reinit'); 599 600 this.options.pager.pages = []; 601 this.options.pager.currentPage = 1; 602 this.options.state.currPage = 1; 603 604 console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!3", this.inOptions); 605 if (this.options.pager.appendTo) { 606 console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!4", jQuery(this.options.pager.appendTo)); 607 jQuery(this.options.pager.appendTo).each(function (index, ui) { 608 jQuery(ui).children().remove(); 609 console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!5", ui); 610 }); 611 } 612 613 this._create(this.inOptions, this.inCallback); 614 }, 615 616 // Bind to scroll 617 bind: function infscr_bind() { 618 this._binding('bind'); 619 }, 620 621 // Destroy current instance of plugin 622 destroy: function infscr_destroy() { 623 624 this.options.state.isDestroyed = true; 625 return this._error('destroy'); 626 627 }, 628 629 // Set pause value to false 630 pause: function infscr_pause() { 631 this._pausing('pause'); 632 }, 633 634 // Set pause value to false 635 resume: function infscr_resume() { 636 this._pausing('resume'); 637 }, 638 639 // Retrieve next set of content items 640 retrieve: function infscr_retrieve(pageNum) { 641 642 var instance = this, 643 opts = instance.options, 644 path = opts.path, 645 box, frag, desturl, method, condition, 646 pageNum = pageNum || null, 647 getPage = (!!pageNum) ? pageNum : opts.state.currPage; 648 beginAjax = function infscr_ajax(opts) { 649 650 // increment the URL bit. e.g. /page/3/ 651 opts.state.currPage++; 652 653 instance._debug('heading into ajax', path); 654 655 // if we're dealing with a table we can't use DIVs 656 box = $(opts.contentSelector).is('table') ? $('<tbody/>') : $('<div/>'); 657 658 desturl = path.join(opts.state.currPage); 659 // HACK: move to options param strip 660 desturl = desturl.replace(/[\?|\&]ajax=1/g, ''); 661 662 method = (opts.dataType == 'html' || opts.dataType == 'json') ? opts.dataType : 'html+callback'; 663 if (opts.appendCallback && opts.dataType == 'html') method += '+callback' 664 665 switch (method) { 666 667 case 'html+callback': 668 669 instance._debug('Using HTML via .load() method: ' + desturl); 670 box.load(desturl + ' ' + opts.itemSelector, null, function infscr_ajax_callback(responseText) { 671 instance._loadcallback(box, responseText); 672 }); 673 674 break; 675 676 case 'html': 677 case 'json': 678 679 instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method'); 680 $.ajax({
681 // params 682 url: desturl, 683 dataType: opts.dataType, 684 complete: function infscr_ajax_callback(jqXHR, textStatus) { 685 condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === "success" || textStatus === "notmodified"); 686 (condition) ? instance._loadcallback(box, jqXHR.responseText) : instance._error('end'); 687 } 688 }); 689 690 break; 691 } 692 }; 693 694 // if behavior is defined and this function is extended, call that instead of default 695 if (!!opts.behavior && this['retrieve_'+opts.behavior] !== undefined) { 696 this['retrieve_'+opts.behavior].call(this,pageNum); 697 return; 698 } 699 700 701 // for manual triggers, if destroyed, get out of here 702 if (opts.state.isDestroyed) { 703 this._debug('Instance is destroyed'); 704 return false; 705 }; 706 707 // we dont want to fire the ajax multiple times 708 opts.state.isDuringAjax = true; 709 710 opts.loading.start.call($(opts.contentSelector)[0],opts); 711 712 }, 713 714 // Check to see next page is needed 715 scroll: function infscr_scroll() { 716 717 var opts = this.options, 718 state = opts.state; 719 720 // distance from nav links to bottom 721 // computed as: height of the document + top offset of container - top offset of nav link 722 opts.pixelsFromNavToBottom = ($(document).height() - $(opts.navSelector).offset().top) + opts.bottomDelta; 723 724 // if behavior is defined and this function is extended, call that instead of default 725 if (!!opts.behavior && this['scroll_'+opts.behavior] !== undefined) { 726 this['scroll_'+opts.behavior].call(this); 727 return; 728 } 729 730 if (state.isDuringAjax || state.isInvalidPage || state.isDone || state.isDestroyed || state.isPaused) return; 731 732 if (!this._nearbottom()) return; 733 734 this.retrieve(); 735 736 }, 737 738 // Toggle pause value 739 toggle: function infscr_toggle() { 740 this._pausing(); 741 }, 742 743 // Unbind from scroll 744 unbind: function infscr_unbind() { 745 this._binding('unbind'); 746 }, 747 748 // update options 749 update: function infscr_options(key) { 750 if ($.isPlainObject(key)) { 751 this.options = $.extend(true,this.options,key); 752 } 753 } 754 755 } 756 757 758 /* 759 ---------------------------- 760 Infinite Scroll function 761 ---------------------------- 762 763 Borrowed logic from the following... 764 765 jQuery UI 766 - https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js 767 768 jCarousel 769 - https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js 770 771 Masonry 772 - https://github.com/desandro/masonry/blob/master/jquery.masonry.js 773 774 */ 775 776 $.fn.infinitescroll = function infscr_init(options, callback) { 777 778 779 var thisCall = typeof options; 780 781 switch (thisCall) { 782 783 // method 784 case 'string': 785 786 var args = Array.prototype.slice.call(arguments, 1); 787 788 this.each(function () { 789 790 var instance = $.data(this, 'infinitescroll'); 791 792 if (!instance) { 793 // not setup yet 794 // return $.error('Method ' + options + ' cannot be called until Infinite Scroll is setup'); 795 return false; 796 } 797 if (!$.isFunction(instance[options]) || options.charAt(0) === "_") { 798 // return $.error('No such method ' + options + ' for Infinite Scroll'); 799 return false; 800 } 801 802 // no errors! 803 instance[options].apply(instance, args); 804 805 }); 806 807 break; 808 809 // creation 810 case 'object': 811 812 this.each(function () { 813 814 var instance = $.data(this, 'infinitescroll'); 815 816 if (instance) { 817 818 // update options of current instance 819 instance.update(options); 820 821 } else { 822 823 // initialize new instance 824 $.data(this, 'infinitescroll', new $.infinitescroll(options, callback, this)); 825 826 } 827 828 }); 829 830 break; 831 832 } 833 834 return this; 835 836 }; 837 838 839 840 /* 841 * smartscroll: debounced scroll event for jQuery * 842 * https://github.com/lukeshumard/smartscroll 843 * Based on smartresize by @louis_remi: https://github.com/lrbabe/jquery.smartresize.js * 844 * Copyright 2011 Louis-Remi & Luke Shumard * Licensed under the MIT license. * 845 */ 846 847 var event = $.event, 848 scrollTimeout; 849 850 event.special.smartscroll = { 851 setup: function () { 852 $(this).bind("scroll", event.special.smartscroll.handler); 853 }, 854 teardown: function () { 855 $(this).unbind("scroll", event.special.smartscroll.handler); 856 }, 857 handler: function (event, execAsap) { 858 // Save the context 859 var context = this, 860 args = arguments; 861 862 // set correct event type 863 event.type = "smartscroll"; 864 865 if (scrollTimeout) { clearTimeout(scrollTimeout); } 866 scrollTimeout = setTimeout(function () {
867 //$.event.handle.apply(context, args); 868 }, execAsap === "execAsap" ? 0 : 100); 869 } 870 }; 871 872 $.fn.smartscroll = function (fn) { 873 return fn ? this.bind("smartscroll", fn) : this.trigger("smartscroll", ["execAsap"]); 874 }; 875 876 877})(window, jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.