是否有其他方法可以在不使用scrollHeight的情况下获取某个HTML元素的内部高度?
事实是,我有一个包含100条记录的表,并且在每条记录中,我使用height = 0然后height = scrollHeight在列中调整某些textarea的大小。
问题是IE至少要执行20〜50ms的scrollHeight取决于大小,我大约有100条记录。这就是说,仅IE呈现所有记录,仅加载100条记录就需要6秒钟以上,如果我需要加载100条记录怎么办?那会毁了我的网站。
因此,我想问的是,scrollHeight是否有其他选择,或者您是否可以提供调整textarea大小的任何其他代码。
谢谢,谢谢
更新
这就是我从IE UI响应中得到的
更新2
第二张图片:如您在下面的图片中看到的,IE之所以缓慢获取特定元素(textarea)的scrollHeight的问题是因为它计算整个布局(html正文)而不是仅获取特定元素的scrollHeight元素(textarea元素)
最佳答案
听起来好像您正在逐行阅读scrollHeight
然后设置height
。这是非常昂贵的,因为写入后的每次读取都会触发重排以便为您提供准确的答案(因为写入可能会更改页面上的某些内容,从而影响所读取的值)。不是height=scrollHeight
需要时间。进行回流是必要的。
layout (write height of all: 0)
reflow
read scrollHeight
write height
reflow (!)
read scrollHeight
write height
reflow (!)
read scrollHeight
write height
...
reflow (!)
paint
(或者也许在每次迭代中都将
height
设置为0;这无关紧要,因为连续的写入不会触发重排。)而是尝试分批执行。将所有
scrollHeight
值读入数组;然后,当您全部拥有它们时,将它们全部设置好。这样,您将只有两次重排:一次是在您开始阅读时,一次是在您完成代码并浏览器需要显示页面时,因为只要您是在阅读或只是在写,就不会发生重排。需要-仅当您从写入到读取值转换时。layout (write height of all: 0)
reflow
read scrollHeight
read scrollHeight
...
write height
write height
reflow
paint
编辑:这是一个黑客;我在淘汰赛中还不够好。但是,作为可能的最小示例,如果您无法以其他任何方式做到,则可能会做到。您可能需要运行它并延伸到“整页”,否则您将看不到任何内容:)
var vm = {
list: ko.observableArray(["foo", "bar\nbaz", "1\n2\n3\n4"])
};
var updatedHeights;
ko.bindingHandlers.autoresizeStart = {
update: function(elem, valueAccessor) {
var data = ko.utils.unwrapObservable(valueAccessor());
console.log("start update; setting updateHeights to []");
updatedHeights = [];
}
};
ko.bindingHandlers.autoresize = {
update: function(elem, valueAccessor) {
console.log("mid update;", elem, "is updated, so let's remember its scrollHeight");
updatedHeights.push([elem, elem.scrollHeight]);
}
};
ko.bindingHandlers.autoresizeEnd = {
update: function(elem, valueAccessor) {
var data = ko.utils.unwrapObservable(valueAccessor());
console.log("end update; lets set heights for all updated elements:");
updatedHeights.forEach(function(elemWithHeight) {
console.log(" ", elemWithHeight[1], elemWithHeight[0]);
elemWithHeight[0].style.height = elemWithHeight[1] + "px";
});
console.log("all done :)");
}
};
ko.virtualElements.allowedBindings.autoresizeStart = true;
ko.virtualElements.allowedBindings.autoresizeEnd = true;
ko.applyBindings(vm);
setTimeout(function() {
vm.list.push("a\nb\nc\nd\ne\nf\ng");
}, 1000);
<!-- results pane console output; see http://meta.stackexchange.com/a/242491 -->
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<!-- ko autoresizeStart: list --><!-- /ko -->
<ul data-bind="foreach: list">
<li >
<textarea data-bind="text: $data, autoresize: $data"></textarea>
</li>
</ul>
<!-- ko autoresizeEnd: list --><!-- /ko -->