我正在寻找有关获取存储在内存中而不是 dom 本身中的多个元素的高度/宽度的最快方法的建议。
首先是一些背景:
此应用程序涉及列样式布局中许多元素的水平滚动,其中大多数包含可能缩放或不缩放的图像。
虽然 IE 和 Firefox 处理得很好,但 Chrome 却没有。在 Chrome 中,当我们开始达到 200 个左右的缩放图像时,我们会变慢。根据我的研究,很明显这取决于 chrome 缩放图像的方式。
因此,我采用了无限滚动样式的方法。在内存中创建了一个对象数组,每个对象引用内存中的一些 html 以及各种其他属性,例如其左/上位置。
我们在滚动过程中监控视口,添加任何新出现的可见元素并删除任何隐藏的元素。让浏览器在任何给定时间只需要处理大约 10-15 个缩放图像。
结果在所有浏览器中都是完美的。但是有一个轻微的并发症。我们使用媒体查询来确定列宽,因此 dom 元素本身将根据视口大小调整大小。
当所有元素都在 dom 中时,检索它们的高度/宽度以执行它们的位置计算很容易。现在当然元素存储在内存数组中,因此为了检索它们的高度/宽度,我们需要暂时将它们放回 dom,检索数据,再次删除它们,然后执行布局计算以重新定位元素进入他们的专栏。
我这样做的方式如下:
reLayoutStream : function(){
var self = this;
var elLength = self.cache.sections.length;
var refHeight = self.cache.stream.offsetHeight;
self.cache.streamoffset = (self.getfastLeftOffset(self.cache.stream) + self.scrollbarleft);
if(elLength){
var marginright = 15;
var marginbottom = 5;
var top = 0;
var left = 0;
var csstransform = self.getsupportedprop(['transform', 'MozTransform', 'WebkitTransform', 'msTransform', 'OTransform']);
for (var i = 0, len = elLength; i < len; i++) {
// THIS IS THE PART THAT CONCERNS ME
var tempnode = self.cache.sections[i].html.cloneNode(true);
tempnode.style.visibility = 'hidden';
self.cache.stream.appendChild(tempnode);
self.cache.sections[i].width = tempnode.offsetWidth;
self.cache.sections[i].height = tempnode.offsetHeight;
self.cache.stream.removeChild(tempnode);
//
var el = self.cache.sections[i].html;
var width = self.cache.sections[i].width;
var height = self.cache.sections[i].height;
if((top + height) > refHeight){
top = 0;
left += (width + marginright);
}
self.cache.sections[i].visible = false;
self.cache.sections[i].offset = (left + self.cache.streamoffset);
self.cache.sections[i].left = left;
self.cache.sections[i].top = top;
if(csstransform){
el.style[csstransform] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';
}
else {
el.style.top = top + 'px';
el.style.left = left +'px';
}
top += (height + marginbottom);
if(i == (elLength-1)){
left += width;
}
}
self.cache.stream.style.width = left + 'px';
self.cache.scrollstart = 0;
self.cache.scrollend = elLength;
self.cache.stream.innerHTML = '';
self.checkVis(true);
}
},
以上是我目前完成的重新布局功能。一旦调整大小停止,这会在调整大小时以节流的方式调用,以保持快速调整浏览器的大小。
在这个函数中有以下部分:
for (var i = 0, len = elLength; i < len; i++) {
var tempnode = self.cache.sections[i].html.cloneNode(true);
tempnode.style.visibility = 'hidden';
self.cache.stream.appendChild(tempnode);
self.cache.sections[i].width = tempnode.offsetWidth;
self.cache.sections[i].height = tempnode.offsetHeight;
self.cache.stream.removeChild(tempnode);
}
这是我关心的部分。我想知道是否有更快的方法将所有这些内存元素添加到 dom,检索它们的高度/宽度数据,然后删除它们。
我考虑过创建一个临时片段,将元素附加到该片段,然后将整个片段插入到 dom 中,以避免将多个子节点附加到 DOM 节点中,但是我肯定会被要求再次遍历元素为了检索它们的属性。这会更快吗?或者有没有更快的方法?
提前致谢。