flow.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /**
  2. @Name:layui.flow 流加载
  3. @Author:贤心
  4. @License:MIT
  5. */
  6. layui.define('jquery', function(exports){
  7. "use strict";
  8. var $ = layui.$, Flow = function(options){}
  9. ,ELEM_MORE = 'layui-flow-more'
  10. ,ELEM_LOAD = '<i class="layui-anim layui-anim-rotate layui-anim-loop layui-icon ">&#xe63e;</i>';
  11. //主方法
  12. Flow.prototype.load = function(options){
  13. var that = this, page = 0, lock, isOver, lazyimg, timer;
  14. options = options || {};
  15. var elem = $(options.elem); if(!elem[0]) return;
  16. var scrollElem = $(options.scrollElem || document); //滚动条所在元素
  17. var mb = options.mb || 50; //与底部的临界距离
  18. var isAuto = 'isAuto' in options ? options.isAuto : true; //是否自动滚动加载
  19. var end = options.end || '没有更多了'; //“末页”显示文案
  20. //滚动条所在元素是否为document
  21. var notDocment = options.scrollElem && options.scrollElem !== document;
  22. //加载更多
  23. var ELEM_TEXT = '<cite>加载更多</cite>'
  24. ,more = $('<div class="layui-flow-more"><a href="javascript:;">'+ ELEM_TEXT +'</a></div>');
  25. if(!elem.find('.layui-flow-more')[0]){
  26. elem.append(more);
  27. }
  28. //加载下一个元素
  29. var next = function(html, over){
  30. html = $(html);
  31. more.before(html);
  32. over = over == 0 ? true : null;
  33. over ? more.html(end) : more.find('a').html(ELEM_TEXT);
  34. isOver = over;
  35. lock = null;
  36. lazyimg && lazyimg();
  37. };
  38. //触发请求
  39. var done = function(){
  40. lock = true;
  41. more.find('a').html(ELEM_LOAD);
  42. typeof options.done === 'function' && options.done(++page, next);
  43. };
  44. done();
  45. //不自动滚动加载
  46. more.find('a').on('click', function(){
  47. var othis = $(this);
  48. if(isOver) return;
  49. lock || done();
  50. });
  51. //如果允许图片懒加载
  52. if(options.isLazyimg){
  53. var lazyimg = that.lazyimg({
  54. elem: options.elem + ' img'
  55. ,scrollElem: options.scrollElem
  56. });
  57. }
  58. if(!isAuto) return that;
  59. scrollElem.on('scroll', function(){
  60. var othis = $(this), top = othis.scrollTop();
  61. if(timer) clearTimeout(timer);
  62. if(isOver) return;
  63. timer = setTimeout(function(){
  64. //计算滚动所在容器的可视高度
  65. var height = notDocment ? othis.height() : $(window).height();
  66. //计算滚动所在容器的实际高度
  67. var scrollHeight = notDocment
  68. ? othis.prop('scrollHeight')
  69. : document.documentElement.scrollHeight;
  70. //临界点
  71. if(scrollHeight - top - height <= mb){
  72. lock || done();
  73. }
  74. }, 100);
  75. });
  76. return that;
  77. };
  78. //图片懒加载
  79. Flow.prototype.lazyimg = function(options){
  80. var that = this, index = 0, haveScroll;
  81. options = options || {};
  82. var scrollElem = $(options.scrollElem || document); //滚动条所在元素
  83. var elem = options.elem || 'img';
  84. //滚动条所在元素是否为document
  85. var notDocment = options.scrollElem && options.scrollElem !== document;
  86. //显示图片
  87. var show = function(item, height){
  88. var start = scrollElem.scrollTop(), end = start + height;
  89. var elemTop = notDocment ? function(){
  90. return item.offset().top - scrollElem.offset().top + start;
  91. }() : item.offset().top;
  92. /* 始终只加载在当前屏范围内的图片 */
  93. if(elemTop >= start && elemTop <= end){
  94. if(!item.attr('src')){
  95. var src = item.attr('lay-src');
  96. layui.img(src, function(){
  97. var next = that.lazyimg.elem.eq(index);
  98. item.attr('src', src).removeAttr('lay-src');
  99. /* 当前图片加载就绪后,检测下一个图片是否在当前屏 */
  100. next[0] && render(next);
  101. index++;
  102. });
  103. }
  104. }
  105. }, render = function(othis, scroll){
  106. //计算滚动所在容器的可视高度
  107. var height = notDocment ? (scroll||scrollElem).height() : $(window).height();
  108. var start = scrollElem.scrollTop(), end = start + height;
  109. that.lazyimg.elem = $(elem);
  110. if(othis){
  111. show(othis, height);
  112. } else {
  113. //计算未加载过的图片
  114. for(var i = 0; i < that.lazyimg.elem.length; i++){
  115. var item = that.lazyimg.elem.eq(i), elemTop = notDocment ? function(){
  116. return item.offset().top - scrollElem.offset().top + start;
  117. }() : item.offset().top;
  118. show(item, height);
  119. index = i;
  120. //如果图片的top坐标,超出了当前屏,则终止后续图片的遍历
  121. if(elemTop > end) break;
  122. }
  123. }
  124. };
  125. render();
  126. if(!haveScroll){
  127. var timer;
  128. scrollElem.on('scroll', function(){
  129. var othis = $(this);
  130. if(timer) clearTimeout(timer)
  131. timer = setTimeout(function(){
  132. render(null, othis);
  133. }, 50);
  134. });
  135. haveScroll = true;
  136. }
  137. return render;
  138. };
  139. //暴露接口
  140. exports('flow', new Flow());
  141. });