gpt4 book ai didi

javascript - 在 HTML Treeview 中拉伸(stretch)节点的性能不佳

转载 作者:太空宇宙 更新时间:2023-11-03 18:36:01 25 4
gpt4 key购买 nike

我创建了一个 HTML TreeView ,其行为类似于 Visual Studio 2012 中的解决方案资源管理器,其中树的每个节点都被拉伸(stretch)以填充其容器的剩余空间,如您在这张图片中所见:

Visual Studio 2012 solution explorer

为了实现这种行为,我用 Javascript 创建了一个无序列表来填充我的树——DOM 结构看起来像这样:

<ul>
<li>
<input type="checkbox" id="node_xy" />
<label for="node_xy" /> <!-- expand/collapse button -->
<a href="javascript:nodeClickHandler();"> <!-- node text --> </a>
<ul>
<!-- subtree with li elements... -->
</ul>
</li>
</ul>

填充树后,我使用 Javascript (jQuery) 调整每个节点的宽度以填充其容器的剩余空间。容器宽度是固定的,但它是可滚动的(就像在 Visual Studio 中一样),因此每当用户展开或折叠树中的节点时,我都必须采取相同的宽度调整步骤,因为树的最大宽度可能会发生变化。代码的宽度调整部分如下所示:

updateLayout: function (containerWidth) {
var self = $(this);
self.find('.treeview a').css('width', ''); /* remove the width property for the next calculation */

var maxAWidth = $('.treeview a').max(function () {
return $(this).offset().left + $(this).outerWidth();
});

var targetWidth = containerWidth || $('.treeview').width();
targetWidth = Math.max(targetWidth, maxAWidth);

$('.treeview a').each(function () {
var left = $(this).offset().left;
$(this).outerWidth(targetWidth - left);
});
}

它工作正常,但是当树中有很多(几百或一千)个节点并且用户想要展开或折叠一个节点时它会变得非常慢。在这些情况下(每次展开/折叠需要 1-2 秒的计算)性能非常糟糕,因为 updateLayout 方法遍历了我的 TreeView 下的完整 DOM 树。我想知道这个“拉伸(stretch)”问题是否有其他不使用这种遍历的解决方案?如果我能用某种纯 CSS 魔法解决这个问题就好了,但这似乎根本不可能......

更新:

标准的 jQuery 优化(例如将查询结果提取到变量等)不起作用。例如,下面的代码并不比旧代码快:

    updateLayout: function (containerWidth) {
var self = $(this);
var treeviewLinks = self.find('.treeview a').css('width', '').get();

var maxAWidth = -Infinity;
for(var i = 0; i < treeviewLinks.length; i++) {
var link = $(treeviewLinks[i]);
if(link.offset().left + link.outerWidth() > maxAWidth)
maxAWidth = link.offset().left + link.outerWidth();
}
var targetWidth = containerWidth || $('.treeview').width();
targetWidth = Math.max(targetWidth, maxAWidth);

for(var i = 0; i < treeviewLinks.length; i++) {
var link = $(treeviewLinks[i]);
link.outerWidth(targetWidth - link.offset().left);
}
}

但是,我能够通过对树中的所有节点使用相同的宽度来加快 updateLayout 步骤:

    updateLayout: function (containerWidth) {
var treeviewLinks = $(this).find('.treeview a');
$('#treeViewItemStyle').remove();

var maxAWidth = treeviewLinks.max(function () {
return $(this).offset().left + $(this).outerWidth();
});

var targetWidth = containerWidth || $('.treeview').width();
targetWidth = Math.max(targetWidth, maxAWidth);
$('<style id="treeViewItemStyle" type="text/css"> #treeview a { width: '
+ (targetWidth - 19) + 'px !important; } </style>')
.appendTo('head');
}

通过此优化,updateLayout 运行得更快,但由于宽度相同,容器的最终宽度将比需要的更大。我目前正在寻找其他解决方案以使其变得更好...

最佳答案

首先,你用了很多重复的查询,完全没有必要,存下你的

$('.treeview a')

在一个变量中并重用它。除此之外,不要遍历整个 DOM,而是尝试只选择需要更改的元素,例如,只选择用户点击的最近元素的子列表。

关于javascript - 在 HTML Treeview 中拉伸(stretch)节点的性能不佳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18657013/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com