1 /** 2 * @fileOverview Dynamic load waterfall items by monitor window scroll. 3 * @author yiminghe@gmail.com 4 */ 5 KISSY.add("waterfall/loader", function (S, Node, Waterfall) { 6 7 var $ = Node.all, 8 win = S.Env.host, 9 // > timeChunk interval to allow adjust first 10 SCROLL_TIMER = 50; 11 12 /** 13 * @name Loader 14 * @extends Waterfall 15 * @class 16 * Dynamic load waterfall items by monitor window scroll. 17 * @memberOf Waterfall 18 */ 19 function Loader() { 20 Loader.superclass.constructor.apply(this, arguments); 21 } 22 23 function doScroll() { 24 var self = this; 25 S.log("waterfall:doScroll"); 26 if (self.__loading) { 27 return; 28 } 29 // 如果正在调整中,等会再看 30 // 调整中的高度不确定,现在不适合判断是否到了加载新数据的条件 31 if (self.isAdjusting()) { 32 // 恰好 __onScroll 是 buffered . :) 33 self.__onScroll(); 34 return; 35 } 36 var container = self.get("container"), 37 colHeight = container.offset().top, 38 diff = self.get("diff"), 39 curColHeights = self.get("curColHeights"); 40 // 找到最小列高度 41 if (curColHeights.length) { 42 colHeight += Math.min.apply(Math, curColHeights); 43 } 44 // 动态载 45 // 最小高度(或被用户看到了)低于预加载线 46 if (diff + $(win).scrollTop() + $(win).height() > colHeight) { 47 S.log("waterfall:loading"); 48 loadData.call(self); 49 } 50 } 51 52 function loadData() { 53 var self = this, 54 container = self.get("container"); 55 56 self.__loading = 1; 57 58 var load = self.get("load"); 59 60 load && load(success, end); 61 62 function success(items, callback) { 63 self.__loading = 0; 64 self.addItems(items, callback); 65 } 66 67 function end() { 68 self.end(); 69 } 70 } 71 72 Loader.ATTRS = 73 /** 74 * @lends Waterfall.Loader# 75 */ 76 { 77 /** 78 * Preload distance below viewport. 79 * Default: 0. 80 * @type Number 81 */ 82 diff:{ 83 value:0 84 } 85 }; 86 87 88 S.extend(Loader, Waterfall, 89 /** 90 * @lends Waterfall.Loader# 91 */ 92 { 93 _init:function () { 94 var self = this; 95 Loader.superclass._init.apply(self, arguments); 96 self.__onScroll = S.buffer(doScroll, SCROLL_TIMER, self); 97 // 初始化时立即检测一次,但是要等初始化 adjust 完成后. 98 self.__onScroll(); 99 self.start(); 100 }, 101 102 /** 103 * Start monitor scroll on window. 104 * @since 1.3 105 */ 106 start:function () { 107 var self = this; 108 if (!self.__started) { 109 $(win).on("scroll", self.__onScroll); 110 self.__started = 1; 111 } 112 }, 113 114 /** 115 * Stop monitor scroll on window. 116 */ 117 end:function () { 118 $(win).detach("scroll", this.__onScroll); 119 }, 120 121 /** 122 * Use end instead. 123 * @deprecated 1.3 124 */ 125 pause:function () { 126 this.end(); 127 }, 128 129 /** 130 * Use start instead. 131 * @deprecated 1.3 132 */ 133 resume:function () { 134 this.start(); 135 }, 136 137 /** 138 * Destroy this instance. 139 */ 140 destroy:function () { 141 var self = this; 142 Loader.superclass.destroy.apply(self, arguments); 143 $(win).detach("scroll", self.__onScroll); 144 self.__started = 0; 145 } 146 }); 147 148 return Loader; 149 150 }, { 151 requires:['node', './base'] 152 });