1

我正在寻找有关获取存储在内存中而不是 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 节点中,但是我肯定会被要求再次遍历元素为了检索它们的属性。这会更快吗?或者有没有更快的方法?

提前致谢。

4

0 回答 0