是否有其他方法可以在不使用scrollHeight的情况下获取某个HTML元素的内部高度?

事实是,我有一个包含100条记录的表,并且在每条记录中,我使用height = 0然后height = scrollHeight在列中调整某些textarea的大小。

问题是IE至少要执行20〜50ms的scrollHeight取决于大小,我大约有100条记录。这就是说,仅IE呈现所有记录,仅加载100条记录就需要6秒钟以上,如果我需要加载100条记录怎么办?那会毁了我的网站。

因此,我想问的是,scrollHeight是否有其他选择,或者您是否可以提供调整textarea大小的任何其他代码。

谢谢,谢谢

更新

这就是我从IE UI响应中得到的
javascript - scrollHeight的替代DOM属性-LMLPHP

更新2

第二张图片:如您在下面的图片中看到的,IE之所以缓慢获取特定元素(textarea)的scrollHeight的问题是因为它计算整个布局(html正文)而不是仅获取特定元素的scrollHeight元素(textarea元素)

javascript - scrollHeight的替代DOM属性-LMLPHP

最佳答案

听起来好像您正在逐行阅读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 -->

10-06 06:55