jScroll

jScroll - jQuery Plugin for Infinite Scrolling / Auto-Paging

이 스크립트는 직접 설치하는 용도가 아닙니다. 다른 스크립트에서 메타 지시문 // @require https://update.greatest.deepsurf.us/scripts/9476/48212/jScroll.js을(를) 사용하여 포함하는 라이브러리입니다.

  1. /*!
  2. * jScroll - jQuery Plugin for Infinite Scrolling / Auto-Paging
  3. * http://jscroll.com/
  4. *
  5. * Copyright 2011-2013, Philip Klauzinski
  6. * http://klauzinski.com/
  7. * Dual licensed under the MIT and GPL Version 2 licenses.
  8. * http://jscroll.com/#license
  9. * http://www.opensource.org/licenses/mit-license.php
  10. * http://www.gnu.org/licenses/gpl-2.0.html
  11. *
  12. * @author Philip Klauzinski
  13. * @version 2.3.1
  14. * @requires jQuery v1.4.3+
  15. * @preserve
  16. */
  17. (function($) {
  18.  
  19. 'use strict';
  20.  
  21. // Define the jscroll namespace and default settings
  22. $.jscroll = {
  23. defaults: {
  24. debug: false,
  25. autoTrigger: true,
  26. autoTriggerUntil: false,
  27. loadingHtml: '<small>Loading...</small>',
  28. padding: 0,
  29. nextSelector: 'a:last',
  30. contentSelector: '',
  31. pagingSelector: '',
  32. callback: false
  33. }
  34. };
  35.  
  36. // Constructor
  37. var jScroll = function($e, options) {
  38.  
  39. // Private vars and methods
  40. var _data = $e.data('jscroll'),
  41. _userOptions = (typeof options === 'function') ? { callback: options } : options,
  42. _options = $.extend({}, $.jscroll.defaults, _userOptions, _data || {}),
  43. _isWindow = ($e.css('overflow-y') === 'visible'),
  44. _$next = $e.find(_options.nextSelector).first(),
  45. _$window = $(window),
  46. _$body = $('body'),
  47. _$scroll = _isWindow ? _$window : $e,
  48. _nextHref = $.trim(_$next.attr('href') + ' ' + _options.contentSelector),
  49.  
  50. // Check if a loading image is defined and preload
  51. _preloadImage = function() {
  52. var src = $(_options.loadingHtml).filter('img').attr('src');
  53. if (src) {
  54. var image = new Image();
  55. image.src = src;
  56. }
  57. },
  58.  
  59. // Wrapper inner content, if it isn't already
  60. _wrapInnerContent = function() {
  61. if (!$e.find('.jscroll-inner').length) {
  62. $e.contents().wrapAll('<div class="jscroll-inner" />');
  63. }
  64. },
  65.  
  66. // Find the next link's parent, or add one, and hide it
  67. _nextWrap = function($next) {
  68. var $parent;
  69. if (_options.pagingSelector) {
  70. $next.closest(_options.pagingSelector).hide();
  71. } else {
  72. $parent = $next.parent().not('.jscroll-inner,.jscroll-added').addClass('jscroll-next-parent').hide();
  73. if (!$parent.length) {
  74. $next.wrap('<div class="jscroll-next-parent" />').parent().hide();
  75. }
  76. }
  77. },
  78.  
  79. // Remove the jscroll behavior and data from an element
  80. _destroy = function() {
  81. return _$scroll.unbind('.jscroll')
  82. .removeData('jscroll')
  83. .find('.jscroll-inner').children().unwrap()
  84. .filter('.jscroll-added').children().unwrap();
  85. },
  86.  
  87. // Observe the scroll event for when to trigger the next load
  88. _observe = function() {
  89. _wrapInnerContent();
  90. var $inner = $e.find('div.jscroll-inner').first(),
  91. data = $e.data('jscroll'),
  92. borderTopWidth = parseInt($e.css('borderTopWidth'), 10),
  93. borderTopWidthInt = isNaN(borderTopWidth) ? 0 : borderTopWidth,
  94. iContainerTop = parseInt($e.css('paddingTop'), 10) + borderTopWidthInt,
  95. iTopHeight = _isWindow ? _$scroll.scrollTop() : $e.offset().top,
  96. innerTop = $inner.length ? $inner.offset().top : 0,
  97. iTotalHeight = Math.ceil(iTopHeight - innerTop + _$scroll.height() + iContainerTop);
  98.  
  99. if (!data.waiting && iTotalHeight + _options.padding >= $inner.outerHeight()) {
  100. //data.nextHref = $.trim(data.nextHref + ' ' + _options.contentSelector);
  101. _debug('info', 'jScroll:', $inner.outerHeight() - iTotalHeight, 'from bottom. Loading next request...');
  102. return _load();
  103. }
  104. },
  105.  
  106. // Check if the href for the next set of content has been set
  107. _checkNextHref = function(data) {
  108. data = data || $e.data('jscroll');
  109. if (!data || !data.nextHref) {
  110. _debug('warn', 'jScroll: nextSelector not found - destroying');
  111. _destroy();
  112. return false;
  113. } else {
  114. _setBindings();
  115. return true;
  116. }
  117. },
  118.  
  119. _setBindings = function() {
  120. var $next = $e.find(_options.nextSelector).first();
  121. if (_options.autoTrigger && (_options.autoTriggerUntil === false || _options.autoTriggerUntil > 0)) {
  122. _nextWrap($next);
  123. if (_$body.height() <= _$window.height()) {
  124. _observe();
  125. }
  126. _$scroll.unbind('.jscroll').bind('scroll.jscroll', function() {
  127. return _observe();
  128. });
  129. if (_options.autoTriggerUntil > 0) {
  130. _options.autoTriggerUntil--;
  131. }
  132. } else {
  133. _$scroll.unbind('.jscroll');
  134. $next.bind('click.jscroll', function() {
  135. _nextWrap($next);
  136. _load();
  137. return false;
  138. });
  139. }
  140. },
  141.  
  142. // Load the next set of content, if available
  143. _load = function() {
  144. var $inner = $e.find('div.jscroll-inner').first(),
  145. data = $e.data('jscroll');
  146.  
  147. data.waiting = true;
  148. $inner.append('<div class="jscroll-added" />')
  149. .children('.jscroll-added').last()
  150. .html('<div class="jscroll-loading">' + _options.loadingHtml + '</div>');
  151.  
  152. return $e.animate({scrollTop: $inner.outerHeight()}, 0, function() {
  153. $inner.find('div.jscroll-added').last().load(data.nextHref, function(r, status) {
  154. if (status === 'error') {
  155. return _destroy();
  156. }
  157. var $next = $(this).find(_options.nextSelector).first();
  158. data.waiting = false;
  159. data.nextHref = $next.attr('href') ? $.trim($next.attr('href') + ' ' + _options.contentSelector) : false;
  160. $('.jscroll-next-parent', $e).remove(); // Remove the previous next link now that we have a new one
  161. _checkNextHref();
  162. if (_options.callback) {
  163. _options.callback.call(this);
  164. }
  165. _debug('dir', data);
  166. });
  167. });
  168. },
  169.  
  170. // Safe console debug - http://klauzinski.com/javascript/safe-firebug-console-in-javascript
  171. _debug = function(m) {
  172. if (_options.debug && typeof console === 'object' && (typeof m === 'object' || typeof console[m] === 'function')) {
  173. if (typeof m === 'object') {
  174. var args = [];
  175. for (var sMethod in m) {
  176. if (typeof console[sMethod] === 'function') {
  177. args = (m[sMethod].length) ? m[sMethod] : [m[sMethod]];
  178. console[sMethod].apply(console, args);
  179. } else {
  180. console.log.apply(console, args);
  181. }
  182. }
  183. } else {
  184. console[m].apply(console, Array.prototype.slice.call(arguments, 1));
  185. }
  186. }
  187. };
  188.  
  189. // Initialization
  190. $e.data('jscroll', $.extend({}, _data, {initialized: true, waiting: false, nextHref: _nextHref}));
  191. _wrapInnerContent();
  192. _preloadImage();
  193. _setBindings();
  194.  
  195. // Expose API methods via the jQuery.jscroll namespace, e.g. $('sel').jscroll.method()
  196. $.extend($e.jscroll, {
  197. destroy: _destroy
  198. });
  199. return $e;
  200. };
  201.  
  202. // Define the jscroll plugin method and loop
  203. $.fn.jscroll = function(m) {
  204. return this.each(function() {
  205. var $this = $(this),
  206. data = $this.data('jscroll'), jscroll;
  207.  
  208. // Instantiate jScroll on this element if it hasn't been already
  209. if (data && data.initialized) {
  210. return;
  211. }
  212. jscroll = new jScroll($this, m);
  213. });
  214. };
  215.  
  216. })(jQuery);