index.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  1. module.exports =
  2. /******/ (function(modules) { // webpackBootstrap
  3. /******/ // The module cache
  4. /******/ var installedModules = {};
  5. /******/
  6. /******/ // The require function
  7. /******/ function __webpack_require__(moduleId) {
  8. /******/
  9. /******/ // Check if module is in cache
  10. /******/ if(installedModules[moduleId]) {
  11. /******/ return installedModules[moduleId].exports;
  12. /******/ }
  13. /******/ // Create a new module (and put it into the cache)
  14. /******/ var module = installedModules[moduleId] = {
  15. /******/ i: moduleId,
  16. /******/ l: false,
  17. /******/ exports: {}
  18. /******/ };
  19. /******/
  20. /******/ // Execute the module function
  21. /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  22. /******/
  23. /******/ // Flag the module as loaded
  24. /******/ module.l = true;
  25. /******/
  26. /******/ // Return the exports of the module
  27. /******/ return module.exports;
  28. /******/ }
  29. /******/
  30. /******/
  31. /******/ // expose the modules object (__webpack_modules__)
  32. /******/ __webpack_require__.m = modules;
  33. /******/
  34. /******/ // expose the module cache
  35. /******/ __webpack_require__.c = installedModules;
  36. /******/
  37. /******/ // define getter function for harmony exports
  38. /******/ __webpack_require__.d = function(exports, name, getter) {
  39. /******/ if(!__webpack_require__.o(exports, name)) {
  40. /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
  41. /******/ }
  42. /******/ };
  43. /******/
  44. /******/ // define __esModule on exports
  45. /******/ __webpack_require__.r = function(exports) {
  46. /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  47. /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  48. /******/ }
  49. /******/ Object.defineProperty(exports, '__esModule', { value: true });
  50. /******/ };
  51. /******/
  52. /******/ // create a fake namespace object
  53. /******/ // mode & 1: value is a module id, require it
  54. /******/ // mode & 2: merge all properties of value into the ns
  55. /******/ // mode & 4: return value when already ns object
  56. /******/ // mode & 8|1: behave like require
  57. /******/ __webpack_require__.t = function(value, mode) {
  58. /******/ if(mode & 1) value = __webpack_require__(value);
  59. /******/ if(mode & 8) return value;
  60. /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
  61. /******/ var ns = Object.create(null);
  62. /******/ __webpack_require__.r(ns);
  63. /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
  64. /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
  65. /******/ return ns;
  66. /******/ };
  67. /******/
  68. /******/ // getDefaultExport function for compatibility with non-harmony modules
  69. /******/ __webpack_require__.n = function(module) {
  70. /******/ var getter = module && module.__esModule ?
  71. /******/ function getDefault() { return module['default']; } :
  72. /******/ function getModuleExports() { return module; };
  73. /******/ __webpack_require__.d(getter, 'a', getter);
  74. /******/ return getter;
  75. /******/ };
  76. /******/
  77. /******/ // Object.prototype.hasOwnProperty.call
  78. /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
  79. /******/
  80. /******/ // __webpack_public_path__
  81. /******/ __webpack_require__.p = "";
  82. /******/
  83. /******/
  84. /******/ // Load entry module and return exports
  85. /******/ return __webpack_require__(__webpack_require__.s = 2);
  86. /******/ })
  87. /************************************************************************/
  88. /******/ ([
  89. /* 0 */
  90. /***/ (function(module, exports, __webpack_require__) {
  91. "use strict";
  92. var isIPhone = false;
  93. var deviceWidth = void 0;
  94. var deviceDPR = void 0;
  95. var BASE_DEVICE_WIDTH = 750;
  96. var checkDeviceWidth = function checkDeviceWidth() {
  97. var info = wx.getSystemInfoSync();
  98. // console.log('info', info)
  99. isIPhone = info.platform === 'ios';
  100. var newDeviceWidth = info.screenWidth || 375;
  101. var newDeviceDPR = info.pixelRatio || 2;
  102. if (!isIPhone) {
  103. // HACK switch width and height when landscape
  104. // const newDeviceHeight = info.screenHeight || 375
  105. // 暂时不处理转屏的情况
  106. }
  107. if (newDeviceWidth !== deviceWidth || newDeviceDPR !== deviceDPR) {
  108. deviceWidth = newDeviceWidth;
  109. deviceDPR = newDeviceDPR;
  110. // console.info('Updated device width: ' + newDeviceWidth + 'px DPR ' + newDeviceDPR)
  111. }
  112. };
  113. checkDeviceWidth();
  114. var eps = 1e-4;
  115. var transformByDPR = function transformByDPR(number) {
  116. if (number === 0) {
  117. return 0;
  118. }
  119. number = number / BASE_DEVICE_WIDTH * deviceWidth;
  120. number = Math.floor(number + eps);
  121. if (number === 0) {
  122. if (deviceDPR === 1 || !isIPhone) {
  123. return 1;
  124. }
  125. return 0.5;
  126. }
  127. return number;
  128. };
  129. var rpxRE = /([+-]?\d+(?:\.\d+)?)rpx/gi;
  130. // const inlineRpxRE = /(?::|\s|\(|\/)([+-]?\d+(?:\.\d+)?)rpx/g
  131. var transformRpx = function transformRpx(style, inline) {
  132. if (typeof style !== 'string') {
  133. return style;
  134. }
  135. var re = rpxRE;
  136. return style.replace(re, function (match, num) {
  137. return transformByDPR(Number(num)) + (inline ? 'px' : '');
  138. });
  139. };
  140. module.exports = {
  141. transformRpx: transformRpx
  142. };
  143. /***/ }),
  144. /* 1 */
  145. /***/ (function(module, exports, __webpack_require__) {
  146. "use strict";
  147. module.exports = {};
  148. /***/ }),
  149. /* 2 */
  150. /***/ (function(module, exports, __webpack_require__) {
  151. "use strict";
  152. /**
  153. * recycle-view组件的api使用
  154. * 提供wx.createRecycleContext进行管理功能
  155. */
  156. var RecycleContext = __webpack_require__(3);
  157. /**
  158. * @params options参数是object对象,展开的结构如下
  159. id: recycle-view的id
  160. dataKey: recycle-item的wx:for绑定的数据变量
  161. page: recycle-view所在的页面或组件的实例
  162. itemSize: 函数或者是Object对象,生成每个recycle-item的宽和高
  163. * @return RecycleContext对象
  164. */
  165. module.exports = function (options) {
  166. return new RecycleContext(options);
  167. };
  168. /***/ }),
  169. /* 3 */
  170. /***/ (function(module, exports, __webpack_require__) {
  171. "use strict";
  172. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  173. /* eslint complexity: ["error", {"max": 50}] */
  174. var recycleData = __webpack_require__(1);
  175. var recycleViewportChangeFunc = __webpack_require__(4);
  176. var transformRpx = __webpack_require__(0);
  177. var RECT_SIZE = 200;
  178. // eslint-disable-next-line no-complexity
  179. function RecycleContext(_ref) {
  180. var _this = this;
  181. var id = _ref.id,
  182. dataKey = _ref.dataKey,
  183. page = _ref.page,
  184. itemSize = _ref.itemSize,
  185. useInPage = _ref.useInPage,
  186. placeholderClass = _ref.placeholderClass,
  187. root = _ref.root;
  188. if (!id || !dataKey || !page || !itemSize) {
  189. throw new Error('parameter id, dataKey, page, itemSize is required');
  190. }
  191. if (typeof itemSize !== 'function' && (typeof itemSize === 'undefined' ? 'undefined' : _typeof(itemSize)) !== 'object') {
  192. throw new Error('parameter itemSize must be function or object with key width and height');
  193. }
  194. if ((typeof itemSize === 'undefined' ? 'undefined' : _typeof(itemSize)) === 'object' && (!itemSize.width || !itemSize.height) && (!itemSize.props || !itemSize.queryClass || !itemSize.dataKey)) {
  195. throw new Error('parameter itemSize must be function or object with key width and height');
  196. }
  197. this.id = id;
  198. this.dataKey = dataKey;
  199. this.page = page;
  200. // 加root参数给useInPage单独使用
  201. this.root = root;
  202. this.placeholderClass = placeholderClass;
  203. page._recycleViewportChange = recycleViewportChangeFunc;
  204. this.comp = page.selectComponent('#' + id);
  205. this.itemSize = itemSize;
  206. this.itemSizeOpt = itemSize;
  207. // if (!this.comp) {
  208. // throw `<recycle-view> with id ${id} not found`
  209. // }
  210. this.useInPage = useInPage || false;
  211. if (this.comp) {
  212. this.comp.context = this;
  213. this.comp.setPage(page);
  214. this.comp.setUseInPage(this.useInPage);
  215. }
  216. if (this.useInPage && !this.root) {
  217. throw new Error('parameter root is required when useInPage is true');
  218. }
  219. if (this.useInPage) {
  220. this.oldPageScroll = this.root.onPageScroll;
  221. // 重写onPageScroll事件
  222. this.root.onPageScroll = function (e) {
  223. // this.checkComp();
  224. if (_this.comp) {
  225. _this.comp._scrollViewDidScroll({
  226. detail: {
  227. scrollLeft: 0,
  228. scrollTop: e.scrollTop
  229. }
  230. });
  231. }
  232. _this.oldPageScroll.apply(_this.root, [e]);
  233. };
  234. this.oldReachBottom = this.root.onReachBottom;
  235. this.root.onReachBottom = function (e) {
  236. if (_this.comp) {
  237. _this.comp.triggerEvent('scrolltolower', {});
  238. }
  239. _this.oldReachBottom.apply(_this.root, [e]);
  240. };
  241. this.oldPullDownRefresh = this.root.onPullDownRefresh;
  242. this.root.onPullDownRefresh = function (e) {
  243. if (_this.comp) {
  244. _this.comp.triggerEvent('scrolltoupper', {});
  245. }
  246. _this.oldPullDownRefresh.apply(_this.root, [e]);
  247. };
  248. }
  249. }
  250. RecycleContext.prototype.checkComp = function () {
  251. if (!this.comp) {
  252. this.comp = this.page.selectComponent('#' + this.id);
  253. if (this.comp) {
  254. this.comp.setUseInPage(this.useInPage);
  255. this.comp.context = this;
  256. this.comp.setPage(this.page);
  257. } else {
  258. throw new Error('the recycle-view correspond to this context is detached, pls create another RecycleContext');
  259. }
  260. }
  261. };
  262. RecycleContext.prototype.appendList = function (list, cb) {
  263. this.checkComp();
  264. var id = this.id;
  265. var dataKey = this.dataKey;
  266. if (!recycleData[id]) {
  267. recycleData[id] = {
  268. key: dataKey,
  269. id: id,
  270. list: list,
  271. sizeMap: {},
  272. sizeArray: []
  273. };
  274. } else {
  275. recycleData[id].dataKey = dataKey;
  276. recycleData[id].list = recycleData[id].list.concat(list);
  277. }
  278. this._forceRerender(id, cb);
  279. return this;
  280. };
  281. RecycleContext.prototype._forceRerender = function (id, cb) {
  282. this.isDataReady = true; // 首次调用说明数据已经ready了
  283. // 动态计算高度并缓存
  284. var that = this;
  285. var allrect = null;
  286. var parentRect = null;
  287. var count = 0;
  288. function setPlaceholderImage() {
  289. if (!allrect || !parentRect) return;
  290. var svgRects = [];
  291. for (var i = 0; i < count; i++) {
  292. svgRects.push({
  293. left: allrect[i].left - parentRect.left,
  294. top: allrect[i].top - parentRect.top,
  295. width: allrect[i].width,
  296. height: allrect[i].height
  297. });
  298. }
  299. that.comp.setPlaceholderImage(svgRects, {
  300. width: parentRect.width,
  301. height: parentRect.height
  302. });
  303. }
  304. function newcb() {
  305. if (cb) {
  306. cb();
  307. }
  308. // 计算placeholder, 只有在动态计算高度的时候才支持
  309. if (that.autoCalculateSize && that.placeholderClass) {
  310. var newQueryClass = [];
  311. that.placeholderClass.forEach(function (item) {
  312. newQueryClass.push('.' + that.itemSizeOpt.queryClass + ' .' + item);
  313. });
  314. // newQueryClass.push(`.` + that.itemSizeOpt.queryClass)
  315. count = newQueryClass.length;
  316. wx.createSelectorQuery().selectAll(newQueryClass.join(',')).boundingClientRect(function (rect) {
  317. if (rect.length < count) return;
  318. allrect = rect;
  319. setPlaceholderImage();
  320. }).exec();
  321. wx.createSelectorQuery().select('.' + that.itemSizeOpt.queryClass).boundingClientRect(function (rect) {
  322. parentRect = rect;
  323. setPlaceholderImage();
  324. }).exec();
  325. }
  326. }
  327. if (Object.prototype.toString.call(this.itemSizeOpt) === '[object Object]' && this.itemSizeOpt && !this.itemSizeOpt.width) {
  328. this._recalculateSizeByProp(recycleData[id].list, function (sizeData) {
  329. recycleData[id].sizeMap = sizeData.map;
  330. recycleData[id].sizeArray = sizeData.array;
  331. // 触发强制渲染
  332. that.comp.forceUpdate(newcb);
  333. });
  334. return;
  335. }
  336. var sizeData = this._recalculateSize(recycleData[id].list);
  337. recycleData[id].sizeMap = sizeData.map;
  338. // console.log('size is', sizeData.array, sizeData.map, 'totalHeight', sizeData.totalHeight)
  339. // console.log('sizeArray', sizeData.array)
  340. recycleData[id].sizeArray = sizeData.array;
  341. // 触发强制渲染
  342. this.comp.forceUpdate(cb);
  343. };
  344. function getValue(item, key) {
  345. if (!key) return item;
  346. if (typeof item[key] !== 'undefined') return item[key];
  347. var keyItems = key.split('.');
  348. for (var i = 0; i < keyItems.length; i++) {
  349. item = item[keyItems[i]];
  350. if (typeof item === 'undefined' || (typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object' && !item) {
  351. return undefined;
  352. }
  353. }
  354. return item;
  355. }
  356. function getValues(item, keys) {
  357. if (Object.prototype.toString.call(keys) !== '[object Array]') {
  358. keys = [keys];
  359. }
  360. var vals = {};
  361. for (var i = 0; i < keys.length; i++) {
  362. vals[keys[i]] = getValue(item, keys[i]);
  363. }
  364. return vals;
  365. }
  366. function isArray(arr) {
  367. return Object.prototype.toString.call(arr) === '[object Array]';
  368. }
  369. function isSamePureValue(item1, item2) {
  370. if ((typeof item1 === 'undefined' ? 'undefined' : _typeof(item1)) !== (typeof item2 === 'undefined' ? 'undefined' : _typeof(item2))) return false;
  371. if (isArray(item1) && isArray(item2)) {
  372. if (item1.length !== item2.length) return false;
  373. for (var i = 0; i < item1.length; i++) {
  374. if (item1[i] !== item2[i]) return false;
  375. }
  376. return true;
  377. }
  378. return item1 === item2;
  379. }
  380. function isSameValue(item1, item2, keys) {
  381. if (!isArray(keys)) {
  382. keys = [keys];
  383. }
  384. for (var i = 0; i < keys.length; i++) {
  385. if (!isSamePureValue(getValue(item1, keys[i]), getValue(item2, keys[i]))) return false;
  386. }
  387. return true;
  388. }
  389. RecycleContext.prototype._recalculateSizeByProp = function (list, cb) {
  390. var itemSize = this.itemSizeOpt;
  391. var propValueMap = this.propValueMap || [];
  392. var calcNewItems = [];
  393. var needCalcPropIndex = [];
  394. if (itemSize.cacheKey) {
  395. propValueMap = wx.getStorageSync(itemSize.cacheKey) || [];
  396. // eslint-disable-next-line no-console
  397. // console.log('[recycle-view] get itemSize from cache', propValueMap)
  398. }
  399. this.autoCalculateSize = true;
  400. var item2PropValueMap = [];
  401. for (var i = 0; i < list.length; i++) {
  402. var item2PropValueIndex = propValueMap.length;
  403. if (!propValueMap.length) {
  404. var val = getValues(list[i], itemSize.props);
  405. val.__index__ = i;
  406. propValueMap.push(val);
  407. calcNewItems.push(list[i]);
  408. needCalcPropIndex.push(item2PropValueIndex);
  409. item2PropValueMap.push({
  410. index: i,
  411. sizeIndex: item2PropValueIndex
  412. });
  413. continue;
  414. }
  415. var found = false;
  416. for (var j = 0; j < propValueMap.length; j++) {
  417. if (isSameValue(propValueMap[j], list[i], itemSize.props)) {
  418. item2PropValueIndex = j;
  419. found = true;
  420. break;
  421. }
  422. }
  423. if (!found) {
  424. var _val = getValues(list[i], itemSize.props);
  425. _val.__index__ = i;
  426. propValueMap.push(_val);
  427. calcNewItems.push(list[i]);
  428. needCalcPropIndex.push(item2PropValueIndex);
  429. }
  430. item2PropValueMap.push({
  431. index: i,
  432. sizeIndex: item2PropValueIndex
  433. });
  434. }
  435. // this.item2PropValueMap = item2PropValueMap
  436. this.propValueMap = propValueMap;
  437. if (propValueMap.length > 10) {
  438. // eslint-disable-next-line no-console
  439. console.warn('[recycle-view] get itemSize count exceed maximum of 10, now got', propValueMap);
  440. }
  441. // console.log('itemsize', propValueMap, item2PropValueMap)
  442. // 预先渲染
  443. var that = this;
  444. function newItemSize(item, index) {
  445. var sizeIndex = item2PropValueMap[index];
  446. if (!sizeIndex) {
  447. // eslint-disable-next-line no-console
  448. console.error('[recycle-view] auto calculate size array error, no map size found', item, index, item2PropValueMap);
  449. throw new Error('[recycle-view] auto calculate size array error, no map size found');
  450. }
  451. var size = propValueMap[sizeIndex.sizeIndex];
  452. if (!size) {
  453. // eslint-disable-next-line no-console
  454. console.log('[recycle-view] auto calculate size array error, no size found', item, index, sizeIndex, propValueMap);
  455. throw new Error('[recycle-view] auto calculate size array error, no size found');
  456. }
  457. return {
  458. width: size.width,
  459. height: size.height
  460. };
  461. }
  462. function sizeReady(rects) {
  463. rects.forEach(function (rect, index) {
  464. var propValueIndex = needCalcPropIndex[index];
  465. propValueMap[propValueIndex].width = rect.width;
  466. propValueMap[propValueIndex].height = rect.height;
  467. });
  468. that.itemSize = newItemSize;
  469. var sizeData = that._recalculateSize(list);
  470. if (itemSize.cacheKey) {
  471. wx.setStorageSync(itemSize.cacheKey, propValueMap); // 把数据缓存起来
  472. }
  473. if (cb) {
  474. cb(sizeData);
  475. }
  476. }
  477. if (calcNewItems.length) {
  478. var obj = {};
  479. obj[itemSize.dataKey] = calcNewItems;
  480. this.page.setData(obj, function () {
  481. // wx.createSelectorQuery().select(itemSize.componentClass).boundingClientRect(rects => {
  482. // compSize = rects;
  483. // if (compSize && allItemSize) {
  484. // sizeReady();
  485. // }
  486. // }).exec();
  487. wx.createSelectorQuery().selectAll('.' + itemSize.queryClass).boundingClientRect(function (rects) {
  488. sizeReady(rects);
  489. }).exec();
  490. });
  491. } else {
  492. that.itemSize = newItemSize;
  493. var sizeData = that._recalculateSize(list);
  494. if (cb) {
  495. cb(sizeData);
  496. }
  497. }
  498. };
  499. // 当before和after这2个slot发生变化的时候调用一下此接口
  500. RecycleContext.prototype._recalculateSize = function (list) {
  501. // 遍历所有的数据
  502. // 应该最多就千量级的, 遍历没有问题
  503. var sizeMap = {};
  504. var func = this.itemSize;
  505. var funcExist = typeof func === 'function';
  506. var comp = this.comp;
  507. var compData = comp.data;
  508. var offsetLeft = 0;
  509. var offsetTop = 0;
  510. var line = 0;
  511. var column = 0;
  512. var sizeArray = [];
  513. var listLen = list.length;
  514. // 把整个页面拆分成200*200的很多个方格, 判断每个数据落在哪个方格上
  515. for (var i = 0; i < listLen; i++) {
  516. list[i].__index__ = i;
  517. var itemSize = {};
  518. // 获取到每一项的宽和高
  519. if (funcExist) {
  520. // 必须保证返回的每一行的高度一样
  521. itemSize = func && func.call(this, list[i], i);
  522. } else {
  523. itemSize = {
  524. width: func.width,
  525. height: func.height
  526. };
  527. }
  528. itemSize = Object.assign({}, itemSize);
  529. sizeArray.push(itemSize);
  530. // 判断数据落到哪个方格上
  531. // 超过了宽度, 移动到下一行, 再根据高度判断是否需要移动到下一个方格
  532. if (offsetLeft + itemSize.width > compData.width) {
  533. column = 0;
  534. offsetLeft = itemSize.width;
  535. // Fixed issue #22
  536. if (sizeArray.length >= 2) {
  537. offsetTop += sizeArray[sizeArray.length - 2].height || 0; // 加上最后一个数据的高度
  538. } else {
  539. offsetTop += itemSize.height;
  540. }
  541. // offsetTop += sizeArray[sizeArray.length - 2].height // 加上最后一个数据的高度
  542. // 根据高度判断是否需要移动到下一个方格
  543. if (offsetTop >= RECT_SIZE * (line + 1)) {
  544. // fix: 当区块比较大时,会缺失块区域信息
  545. var lastIdx = i - 1;
  546. var lastLine = line;
  547. line += parseInt((offsetTop - RECT_SIZE * line) / RECT_SIZE, 10);
  548. for (var idx = lastLine; idx < line; idx++) {
  549. var _key = idx + '.' + column;
  550. if (!sizeMap[_key]) {
  551. sizeMap[_key] = [];
  552. }
  553. sizeMap[_key].push(lastIdx);
  554. }
  555. }
  556. // 新起一行的元素, beforeHeight是前一个元素的beforeHeight和height相加
  557. if (i === 0) {
  558. itemSize.beforeHeight = 0;
  559. } else {
  560. var prevItemSize = sizeArray[sizeArray.length - 2];
  561. itemSize.beforeHeight = prevItemSize.beforeHeight + prevItemSize.height;
  562. }
  563. } else {
  564. if (offsetLeft >= RECT_SIZE * (column + 1)) {
  565. column++;
  566. }
  567. offsetLeft += itemSize.width;
  568. if (i === 0) {
  569. itemSize.beforeHeight = 0;
  570. } else {
  571. // 同一行的元素, beforeHeight和前面一个元素的beforeHeight一样
  572. itemSize.beforeHeight = sizeArray[sizeArray.length - 2].beforeHeight;
  573. }
  574. }
  575. var key = line + '.' + column;
  576. if (!sizeMap[key]) {
  577. sizeMap[key] = [];
  578. }
  579. sizeMap[key].push(i);
  580. // fix: 当区块比较大时,会缺失块区域信息
  581. if (listLen - 1 === i && itemSize.height > RECT_SIZE) {
  582. var _lastIdx = line;
  583. offsetTop += itemSize.height;
  584. line += parseInt((offsetTop - RECT_SIZE * line) / RECT_SIZE, 10);
  585. for (var _idx = _lastIdx; _idx <= line; _idx++) {
  586. var _key2 = _idx + '.' + column;
  587. if (!sizeMap[_key2]) {
  588. sizeMap[_key2] = [];
  589. }
  590. sizeMap[_key2].push(i);
  591. }
  592. }
  593. }
  594. // console.log('sizeMap', sizeMap)
  595. var obj = {
  596. array: sizeArray,
  597. map: sizeMap,
  598. totalHeight: sizeArray.length ? sizeArray[sizeArray.length - 1].beforeHeight + sizeArray[sizeArray.length - 1].height : 0
  599. };
  600. comp.setItemSize(obj);
  601. return obj;
  602. };
  603. RecycleContext.prototype.deleteList = function (beginIndex, count, cb) {
  604. this.checkComp();
  605. var id = this.id;
  606. if (!recycleData[id]) {
  607. return this;
  608. }
  609. recycleData[id].list.splice(beginIndex, count);
  610. this._forceRerender(id, cb);
  611. return this;
  612. };
  613. RecycleContext.prototype.updateList = function (beginIndex, list, cb) {
  614. this.checkComp();
  615. var id = this.id;
  616. if (!recycleData[id]) {
  617. return this;
  618. }
  619. var len = recycleData[id].list.length;
  620. for (var i = 0; i < list.length && beginIndex < len; i++) {
  621. recycleData[id].list[beginIndex++] = list[i];
  622. }
  623. this._forceRerender(id, cb);
  624. return this;
  625. };
  626. RecycleContext.prototype.update = RecycleContext.prototype.updateList;
  627. RecycleContext.prototype.splice = function (begin, deleteCount, appendList, cb) {
  628. this.checkComp();
  629. var id = this.id;
  630. var dataKey = this.dataKey;
  631. // begin是数组
  632. if ((typeof begin === 'undefined' ? 'undefined' : _typeof(begin)) === 'object' && begin.length) {
  633. cb = deleteCount;
  634. appendList = begin;
  635. }
  636. if (typeof appendList === 'function') {
  637. cb = appendList;
  638. appendList = [];
  639. }
  640. if (!recycleData[id]) {
  641. recycleData[id] = {
  642. key: dataKey,
  643. id: id,
  644. list: appendList || [],
  645. sizeMap: {},
  646. sizeArray: []
  647. };
  648. } else {
  649. recycleData[id].dataKey = dataKey;
  650. var list = recycleData[id].list;
  651. if (appendList && appendList.length) {
  652. list.splice.apply(list, [begin, deleteCount].concat(appendList));
  653. } else {
  654. list.splice(begin, deleteCount);
  655. }
  656. }
  657. this._forceRerender(id, cb);
  658. return this;
  659. };
  660. RecycleContext.prototype.append = RecycleContext.prototype.appendList;
  661. RecycleContext.prototype.destroy = function () {
  662. if (this.useInPage) {
  663. this.page.onPullDownRefresh = this.oldPullDownRefresh;
  664. this.page.onReachBottom = this.oldReachBottom;
  665. this.page.onPageScroll = this.oldPageScroll;
  666. this.oldPageScroll = this.oldReachBottom = this.oldPullDownRefresh = null;
  667. }
  668. this.page = null;
  669. this.comp = null;
  670. if (recycleData[this.id]) {
  671. delete recycleData[this.id];
  672. }
  673. return this;
  674. };
  675. // 重新更新下页面的数据
  676. RecycleContext.prototype.forceUpdate = function (cb, reinitSlot) {
  677. var _this2 = this;
  678. this.checkComp();
  679. if (reinitSlot) {
  680. this.comp.reRender(function () {
  681. _this2._forceRerender(_this2.id, cb);
  682. });
  683. } else {
  684. this._forceRerender(this.id, cb);
  685. }
  686. return this;
  687. };
  688. RecycleContext.prototype.getBoundingClientRect = function (index) {
  689. this.checkComp();
  690. if (!recycleData[this.id]) {
  691. return null;
  692. }
  693. var sizeArray = recycleData[this.id].sizeArray;
  694. if (!sizeArray || !sizeArray.length) {
  695. return null;
  696. }
  697. if (typeof index === 'undefined') {
  698. var list = [];
  699. for (var i = 0; i < sizeArray.length; i++) {
  700. list.push({
  701. left: 0,
  702. top: sizeArray[i].beforeHeight,
  703. width: sizeArray[i].width,
  704. height: sizeArray[i].height
  705. });
  706. }
  707. return list;
  708. }
  709. index = parseInt(index, 10);
  710. if (index >= sizeArray.length || index < 0) return null;
  711. return {
  712. left: 0,
  713. top: sizeArray[index].beforeHeight,
  714. width: sizeArray[index].width,
  715. height: sizeArray[index].height
  716. };
  717. };
  718. RecycleContext.prototype.getScrollTop = function () {
  719. this.checkComp();
  720. return this.comp.currentScrollTop || 0;
  721. };
  722. // 将px转化为rpx
  723. RecycleContext.prototype.transformRpx = RecycleContext.transformRpx = function (str, addPxSuffix) {
  724. if (typeof str === 'number') str += 'rpx';
  725. return parseFloat(transformRpx.transformRpx(str, addPxSuffix));
  726. };
  727. RecycleContext.prototype.getViewportItems = function (inViewportPx) {
  728. this.checkComp();
  729. var indexes = this.comp.getIndexesInViewport(inViewportPx);
  730. if (indexes.length <= 0) return [];
  731. var viewportItems = [];
  732. var list = recycleData[this.id].list;
  733. for (var i = 0; i < indexes.length; i++) {
  734. viewportItems.push(list[indexes[i]]);
  735. }
  736. return viewportItems;
  737. };
  738. RecycleContext.prototype.getTotalHeight = function () {
  739. this.checkComp();
  740. return this.comp.getTotalHeight();
  741. };
  742. // 返回完整的列表数据
  743. RecycleContext.prototype.getList = function () {
  744. if (!recycleData[this.id]) {
  745. return [];
  746. }
  747. return recycleData[this.id].list;
  748. };
  749. module.exports = RecycleContext;
  750. /***/ }),
  751. /* 4 */
  752. /***/ (function(module, exports, __webpack_require__) {
  753. "use strict";
  754. /* eslint complexity: ["error", {"max": 50}] */
  755. var recycleData = __webpack_require__(1);
  756. module.exports = function (e, cb) {
  757. var detail = e.detail;
  758. // console.log('data change transfer use time', Date.now() - e.detail.timeStamp)
  759. var newList = [];
  760. var item = recycleData[detail.id];
  761. // 边界值判断, 避免造成异常, 假设先调用了createRecycleContext, 然后再延迟2s调用append插入数据的情况
  762. if (!item || !item.list) return;
  763. var dataList = item.list;
  764. var pos = detail.data;
  765. var beginIndex = pos.beginIndex;
  766. var endIndex = pos.endIndex;
  767. item.pos = pos;
  768. // 加ignoreBeginIndex和ignoreEndIndex
  769. if (typeof beginIndex === 'undefined' || beginIndex === -1 || typeof endIndex === 'undefined' || endIndex === -1) {
  770. newList = [];
  771. } else {
  772. var i = -1;
  773. for (i = beginIndex; i < dataList.length && i <= endIndex; i++) {
  774. if (i >= pos.ignoreBeginIndex && i <= pos.ignoreEndIndex) continue;
  775. newList.push(dataList[i]);
  776. }
  777. }
  778. var obj = {
  779. // batchSetRecycleData: !this.data.batchSetRecycleData
  780. };
  781. obj[item.key] = newList;
  782. var comp = this.selectComponent('#' + detail.id);
  783. obj[comp.data.batchKey] = !this.data.batchSetRecycleData;
  784. comp._setInnerBeforeAndAfterHeight({
  785. beforeHeight: pos.minTop,
  786. afterHeight: pos.afterHeight
  787. });
  788. this.setData(obj, function () {
  789. if (typeof cb === 'function') {
  790. cb();
  791. }
  792. });
  793. // Fix #1
  794. // 去掉了batchSetDataKey,支持一个页面内显示2个recycle-view
  795. // const groupSetData = () => {
  796. // this.setData(obj)
  797. // comp._recycleInnerBatchDataChanged(() => {
  798. // if (typeof cb === 'function') {
  799. // cb()
  800. // }
  801. // })
  802. // }
  803. // if (typeof this.groupSetData === 'function') {
  804. // this.groupSetData(groupSetData)
  805. // } else {
  806. // groupSetData()
  807. // }
  808. };
  809. /***/ })
  810. /******/ ]);