Просмотр файла wu-static/js/jscroll.js

Размер файла: 4.69Kb
  1. (function($) {
  2. 'use strict';
  3. $.jscroll = {
  4. defaults: {
  5. debug: false,
  6. autoTrigger: true,
  7. autoTriggerUntil: false,
  8. loadingHtml: '<small>Loading...</small>',
  9. padding: 0,
  10. nextSelector: 'a:last',
  11. contentSelector: '',
  12. pagingSelector: '',
  13. callback: false
  14. }
  15. };
  16. var jScroll = function($e, options) {
  17. var _data = $e.data('jscroll'),
  18. _userOptions = (typeof options === 'function') ? { callback: options } : options,
  19. _options = $.extend({}, $.jscroll.defaults, _userOptions, _data || {}),
  20. _isWindow = ($e.css('overflow-y') === 'visible'),
  21. _$next = $e.find(_options.nextSelector).first(),
  22. _$window = $(window),
  23. _$body = $('body'),
  24. _$scroll = _isWindow ? _$window : $e,
  25. _nextHref = $.trim(_$next.attr('href') + ' ' + _options.contentSelector),
  26. _preloadImage = function() {
  27. var src = $(_options.loadingHtml).filter('img').attr('src');
  28. if (src) {
  29. var image = new Image();
  30. image.src = src;
  31. }
  32. },
  33. _wrapInnerContent = function() {
  34. if (!$e.find('.jscroll-inner').length) {
  35. $e.contents().wrapAll('<div class="jscroll-inner" />');
  36. }
  37. },
  38. _nextWrap = function($next) {
  39. var $parent;
  40. if (_options.pagingSelector) {
  41. $next.closest(_options.pagingSelector).hide();
  42. } else {
  43. $parent = $next.parent().not('.jscroll-inner,.jscroll-added').addClass('jscroll-next-parent').hide();
  44. if (!$parent.length) {
  45. $next.wrap('<div class="jscroll-next-parent" />').parent().hide();
  46. }
  47. }
  48. },
  49. _destroy = function() {
  50. $e.removeData('jscroll');
  51. return _$scroll.unbind('.jscroll')
  52. .removeData('jscroll')
  53. .find('.jscroll-inner').children().unwrap()
  54. },
  55. _observe = function() {
  56. _wrapInnerContent();
  57. var $inner = $e.find('div.jscroll-inner').first(),
  58. data = $e.data('jscroll'),
  59. borderTopWidth = parseInt($e.css('borderTopWidth'), 10),
  60. borderTopWidthInt = isNaN(borderTopWidth) ? 0 : borderTopWidth,
  61. iContainerTop = parseInt($e.css('paddingTop'), 10) + borderTopWidthInt,
  62. iTopHeight = _isWindow ? _$scroll.scrollTop() : $e.offset().top,
  63. innerTop = $inner.length ? $inner.offset().top : 0,
  64. iTotalHeight = Math.ceil(iTopHeight - innerTop + _$scroll.height() + iContainerTop);
  65. if (!data.waiting && iTotalHeight + _options.padding >= $inner.outerHeight()) {
  66. _debug('info', 'jScroll:', $inner.outerHeight() - iTotalHeight, 'from bottom. Loading next request...');
  67. return _load();
  68. }
  69. },
  70. _checkNextHref = function(data) {
  71. data = data || $e.data('jscroll');
  72. if (!data || !data.nextHref) {
  73. _debug('warn', 'jScroll: nextSelector not found - destroying');
  74. _destroy();
  75. return false;
  76. } else {
  77. _setBindings();
  78. return true;
  79. }
  80. },
  81. _setBindings = function() {
  82. var $next = $e.find(_options.nextSelector).first();
  83. if (!$next.length) {
  84. return;
  85. }
  86. if (_options.autoTrigger && (_options.autoTriggerUntil === false || _options.autoTriggerUntil > 0)) {
  87. _nextWrap($next);
  88. if (_$body.height() <= _$window.height()) {
  89. _observe();
  90. }
  91. _$scroll.unbind('.jscroll').bind('scroll.jscroll', function() {
  92. return _observe();
  93. });
  94. if (_options.autoTriggerUntil > 0) {
  95. _options.autoTriggerUntil--;
  96. }
  97. } else {
  98. _$scroll.unbind('.jscroll');
  99. $next.bind('click.jscroll', function() {
  100. _nextWrap($next);
  101. _load();
  102. return false;
  103. });
  104. }
  105. },
  106. _load = function() {
  107. var $inner = $e.find('div.jscroll-inner').first(),
  108. data = $e.data('jscroll');
  109. data.waiting = true;
  110. $inner.append('<div class="jscroll-added" />')
  111. .children('.jscroll-added').last()
  112. .html('<div class="jscroll-loading">' + _options.loadingHtml + '</div>');
  113. return $e.animate({scrollTop: $inner.outerHeight()}, 0, function() {
  114. $inner.find('div.jscroll-added').last().load(data.nextHref, function(r, status) {
  115. if (status === 'error') {
  116. return _destroy();
  117. }
  118. var $next = $(this).find(_options.nextSelector).first();
  119. data.waiting = false;
  120. data.nextHref = $next.attr('href') ? $.trim($next.attr('href') + ' ' + _options.contentSelector) : false;
  121. $('.jscroll-next-parent', $e).remove(); // Remove the previous next link now that we have a new one
  122. _checkNextHref();
  123. if (_options.callback) {
  124. _options.callback.call(this);
  125. }
  126. _debug('dir', data);
  127. });
  128. });
  129. },
  130. _debug = function(m) {
  131. if (_options.debug && typeof console === 'object' && (typeof m === 'object' || typeof console[m] === 'function')) {
  132. if (typeof m === 'object') {
  133. var args = [];
  134. for (var sMethod in m) {
  135. if (typeof console[sMethod] === 'function') {
  136. args = (m[sMethod].length) ? m[sMethod] : [m[sMethod]];
  137. console[sMethod].apply(console, args);
  138. } else {
  139. console.log.apply(console, args);
  140. }
  141. }
  142. } else {
  143. console[m].apply(console, Array.prototype.slice.call(arguments, 1));
  144. }
  145. }
  146. };
  147. $e.data('jscroll', $.extend({}, _data, {initialized: true, waiting: false, nextHref: _nextHref}));
  148. _wrapInnerContent();
  149. _preloadImage();
  150. _setBindings();
  151. $.extend($e.jscroll, {
  152. destroy: _destroy
  153. });
  154. return $e;
  155. };
  156. $.fn.jscroll = function(m) {
  157. return this.each(function() {
  158. var $this = $(this),
  159. data = $this.data('jscroll'), jscroll;
  160. if (data && data.initialized) {
  161. return;
  162. }
  163. jscroll = new jScroll($this, m);
  164. });
  165. };
  166. })(jQuery);