diff --git a/changelog.md b/changelog.md
index 8c8bb9ba5..a8520e128 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,6 @@
# 更新日志
2.0(2021-07)
+- 新增bi.virtual_group_list组件
- layout支持forceUpdate刷新方式
- width属性支持calc()
- 修改了颜色选择器交互
diff --git a/examples/dev.html b/examples/dev.html
index d499ed483..3b11585b5 100644
--- a/examples/dev.html
+++ b/examples/dev.html
@@ -2,8 +2,9 @@
-
-
+
+
+
diff --git a/src/base/list/virtualgrouplist.js b/src/base/list/virtualgrouplist.js
new file mode 100644
index 000000000..510ade0d8
--- /dev/null
+++ b/src/base/list/virtualgrouplist.js
@@ -0,0 +1,155 @@
+/**
+ * 同时用于virtualGroup和virtualList特性的虚拟列表
+ *
+ * Created by GUY on 2017/5/22.
+ * @class BI.VirtualList
+ * @extends BI.Widget
+ */
+BI.VirtualGroupList = BI.inherit(BI.Widget, {
+ props: function () {
+ return {
+ baseCls: "bi-virtual-group-list",
+ overscanHeight: 100,
+ blockSize: 10,
+ scrollTop: 0,
+ rowHeight: "auto",
+ items: []
+ };
+ },
+
+ init: function () {
+ var self = this;
+ this.renderedIndex = -1;
+ },
+
+ render: function () {
+ var self = this, o = this.options;
+ return {
+ type: "bi.vertical",
+ items: [{
+ type: "bi.layout",
+ ref: function () {
+ self.topBlank = this;
+ }
+ }, {
+ type: "bi.virtual_group",
+ height: o.rowHeight * o.items.length,
+ ref: function () {
+ self.container = this;
+ },
+ layouts: [{
+ type: "bi.vertical",
+ scrolly: false
+ }]
+ }, {
+ type: "bi.layout",
+ ref: function () {
+ self.bottomBlank = this;
+ }
+ }],
+ element: this
+ };
+ },
+
+ // mounted之后绑定事件
+ mounted: function () {
+ var self = this, o = this.options;
+ this._populate();
+ this.element.scroll(function (e) {
+ o.scrollTop = self.element.scrollTop();
+ self._calculateBlocksToRender();
+ });
+ BI.ResizeDetector.addResizeListener(this, function () {
+ self._calculateBlocksToRender();
+ });
+ },
+
+ _isAutoHeight: function () {
+ return this.options.rowHeight === "auto";
+ },
+
+ _renderMoreIf: function () {
+ var self = this, o = this.options;
+ var height = this.element.height();
+ var minContentHeight = o.scrollTop + height + o.overscanHeight;
+ var index = (this.renderedIndex + 1) * o.blockSize, cnt = this.renderedIndex + 1;
+ var lastHeight;
+ var getElementHeight = function () {
+ return self.container.element.height() + self.topBlank.element.height() + self.bottomBlank.element.height();
+ };
+ while ((lastHeight = getElementHeight()) < minContentHeight && index < o.items.length) {
+ var items = o.items.slice(index, index + o.blockSize);
+ this.container.addItems(items, this);
+ var addedHeight = getElementHeight() - lastHeight;
+ this.tree.set(cnt, addedHeight);
+ this.renderedIndex = cnt;
+ cnt++;
+ index += o.blockSize;
+ }
+ },
+
+ _calculateBlocksToRender: function () {
+ var o = this.options;
+ this._isAutoHeight() && this._renderMoreIf();
+ var height = this.element.height();
+ var minContentHeightFrom = o.scrollTop - o.overscanHeight;
+ var minContentHeightTo = o.scrollTop + height + o.overscanHeight;
+ var start = this.tree.greatestLowerBound(minContentHeightFrom);
+ var end = this.tree.leastUpperBound(minContentHeightTo);
+ var items = [];
+ var topHeight = this.tree.sumTo(Math.max(-1, start - 1));
+ this.topBlank.setHeight(topHeight);
+ if (this._isAutoHeight()) {
+ for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) {
+ var index = i * o.blockSize;
+ for (var j = index; j < index + o.blockSize && j < o.items.length; j++) {
+ items.push(o.items[j]);
+ }
+ }
+ this.bottomBlank.setHeight(this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex)));
+ this.container.element.height(this.container.element.height());
+ this.container.populate(items);
+ this.container.element.height("auto");
+ } else {
+ for (var i = (start < 0 ? 0 : start); i <= end; i++) {
+ var index = i * o.blockSize;
+ for (var j = index; j < index + o.blockSize && j < o.items.length; j++) {
+ items.push(o.items[j]);
+ }
+ }
+ this.container.element.height(o.rowHeight * o.items.length - topHeight);
+ this.container.populate(items);
+ }
+ },
+
+ _populate: function (items) {
+ var o = this.options;
+ if (items && this.options.items !== items) {
+ this.options.items = items;
+ }
+ this.tree = BI.PrefixIntervalTree.uniform(Math.ceil(o.items.length / o.blockSize), this._isAutoHeight() ? 0 : o.rowHeight * o.blockSize);
+
+ this._calculateBlocksToRender();
+ try {
+ this.element.scrollTop(o.scrollTop);
+ } catch (e) {
+ }
+ },
+
+ restore: function () {
+ this.renderedIndex = -1;
+ this.options.scrollTop = 0;
+ // 依赖于cache的占位元素也要初始化
+ this.topBlank.setHeight(0);
+ this.bottomBlank.setHeight(0);
+ },
+
+ populate: function (items) {
+ if (items && this.options.items !== items) {
+ this.restore();
+ }
+ this._populate(items);
+ }
+});
+BI.shortcut("bi.virtual_group_list", BI.VirtualGroupList);
+
diff --git a/src/base/list/virtuallist.js b/src/base/list/virtuallist.js
index 28f2d54d3..f5208cc49 100644
--- a/src/base/list/virtuallist.js
+++ b/src/base/list/virtuallist.js
@@ -1,5 +1,5 @@
/**
- * 表示当前对象
+ * 虚拟列表
*
* Created by GUY on 2017/5/22.
* @class BI.VirtualList
@@ -64,8 +64,7 @@ BI.VirtualList = BI.inherit(BI.Widget, {
var self = this, o = this.options;
var height = this.element.height();
var minContentHeight = o.scrollTop + height + o.overscanHeight;
- var index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + o.blockSize)) || 0,
- cnt = this.renderedIndex + 1;
+ var index = (this.renderedIndex + 1) * o.blockSize, cnt = this.renderedIndex + 1;
var lastHeight;
var getElementHeight = function () {
return self.container.element.height() + self.topBlank.element.height() + self.bottomBlank.element.height();
@@ -94,7 +93,7 @@ BI.VirtualList = BI.inherit(BI.Widget, {
var minContentHeightTo = o.scrollTop + height + o.overscanHeight;
var start = this.tree.greatestLowerBound(minContentHeightFrom);
var end = this.tree.leastUpperBound(minContentHeightTo);
- var needDestroyed = [];
+ var needDestroyed = [], needMount = [];
for (var i = 0; i < start; i++) {
var index = this.cache[i].index;
if (!this.cache[i].destroyed) {
@@ -125,7 +124,8 @@ BI.VirtualList = BI.inherit(BI.Widget, {
}
if (this.cache[i].destroyed === true) {
for (var j = index; j < index + o.blockSize && j < o.items.length; j++) {
- var w = this.container._addElement(j, BI.extend({root: true}, BI.stripEL(o.items[j])), this);
+ var w = this.container._addElement(j, o.items[j], this);
+ needMount.push(w);
currentFragment.appendChild(w.element[0]);
}
this.cache[i].destroyed = false;
@@ -135,6 +135,9 @@ BI.VirtualList = BI.inherit(BI.Widget, {
this.container.element.append(lastFragment);
this.topBlank.setHeight(this.tree.sumTo(Math.max(-1, start - 1)));
this.bottomBlank.setHeight(this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex)));
+ BI.each(needMount, function (i, child) {
+ child && child._mount();
+ });
BI.each(needDestroyed, function (i, child) {
child && child._destroy();
});
@@ -179,7 +182,8 @@ BI.VirtualList = BI.inherit(BI.Widget, {
},
destroyed: function () {
- this.restore();
+ this.cache = {};
+ this.renderedIndex = -1;
}
});
BI.shortcut("bi.virtual_list", BI.VirtualList);
diff --git a/src/less/core/utils/common.less b/src/less/core/utils/common.less
index 2eef73c56..22832e25f 100644
--- a/src/less/core/utils/common.less
+++ b/src/less/core/utils/common.less
@@ -500,6 +500,23 @@
display: none;
}
+ //& .bi-hover-visible-item {
+ // display: none;
+ //}
+ //&:hover .bi-hover-visible-item {
+ // display: block;
+ // &.bi-f-h, &.bi-f-v, &.bi-f-s-h, &.bi-f-s-v {
+ // display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
+ // display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
+ // display: -ms-flexbox; /* TWEENER - IE 10 */
+ // display: -webkit-flex; /* NEW - Chrome */
+ // display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
+ // }
+ // &.i-item {
+ // display: inline-block;
+ // }
+ //}
+
& .bi-hover-visible-item {
visibility: hidden;
}