我有两个html表,包含所有类型的元素(span,input,select,...),我想强制这些表的行具有相同的高度。不幸的是,在tr
或td
does上设置属性'height'不起作用(如果行包含至少一个超过给定高度的元素,则该行更高)。
我还没有找到一种方法可以用css强制行高,所以我编写了一个循环遍历所有行的Javascript函数,用右表中相应行的高度检查左表行的高度如果它们不同,我将高度(改变样式)设置为最大值。
它有效...但如果表格有很多行,它会非常慢!我认为这是因为每种风格的变化都会导致回流。
任何提示?请注意,我无法合并这两个表。
在这里我的代码剪断了,但也许我需要一个完全不同的方法......
var rightTableRows = mainTable.children("tbody").children("tr:parent");
var leftTableRows = colHeader.children("tbody").children("tr:parent");
for (chr=0;chr < leftTableRows .length;chr++) {
var rowLeft = leftTableRows [chr];
var heightleft = rowLeft.offsetHeight;
var rowRight = rightTableRows[chr];
var heightright = rowRight.offsetHeight;
if(heightleft != heightright){
console.log("left: "+heightleft +" - right: "+heightright);
if(heightleft>heightright){
rowRight.setAttribute("style","height:"+heightleft+"px");
}else{
rowLeft.setAttribute("style","height:"+heightright+"px");
}
}
}
您反复阅读然后写入DOM。这被认为是性能的重要禁忌。正确的方法是执行所有“读取”,然后执行所有“写入” - 否则您将强制进行回流/计算。实际上,您最好使用两个循环,一个找到正确的高度,然后是第二个应用它们:
var rightTableRows = mainTable.children("tbody").children("tr:parent");
var leftTableRows = colHeader.children("tbody").children("tr:parent");
var length = leftTableRows.length;
var heights = [];
for (var chr = 0; chr < length; chr++) {
var rowLeft = leftTableRows[chr];
var heightleft = rowLeft.offsetHeight;
var rowRight = rightTableRows[chr];
var heightright = rowRight.offsetHeight;
if (heightleft > heightright) {
heights.push({
elem: rowRight,
height: heightleft
});
} else {
heights.push({
elem: rowLeft,
height: heightright
});
}
}
for (var i = 0; i < heights.length; i++) {
heights[i].elem.style.height = heights[i].height + 'px';
}
现在,元素及其新高度作为对象存储在数组中,然后您只需遍历数组。在第一次循环之后,您再也没有从DOM中读取过。其他优化包括删除不需要的if()
语句,缓存HTML节点列表的长度,特别是编写style.height
而不是setAttribute()
(较慢)。
如果你不知道细胞的最大高度。您应该将表转换为div并使用display flex。
这将允许您拥有所需的行为,但将暗示您更改HTML代码的构造。
不必拥有第一个表和第二个表的元素,而是必须交替一个而另一个。
我将通过jfriend00从这个answer中摘录一下。一定要提出他们的答案。
DOM修改
第2点和第3点非常相关,您将获得每行的offsetHeight,然后设置新值。所以这些变化不是批量的。每次更改都会导致重排,因为您在下一行的下一次迭代中获得了偏移高度。
要优化,请读取所有行并保存内存中的所有挂起更改。然后在新循环中应用新行高。从内存中提取新值的位置。
不确定原因,但是:
将行高设置为td应该增加td的高度,这将增加tr的高度。如果没有,你可以设置在div中封装td的内容,然后在其上设置line-height。
另一个加快速度的选择是为所有元素设置相同的样式类。然后在计算高度后设置类的行高。这将更改使用此类的所有元素的高度。阅读Javascript的styleSheet对象,了解如何做到这一点....