IE8中的clientWidth性能

Ele*_*ent 6 javascript internet-explorer-8

我有一些遗留的javascript,冻结表的tfoot/thead并让身体滚动,它工作正常,除了在IE8中它非常慢.

我跟踪问题来读取tfoot/thead中的单元格的clientWidth属性...在ie6/7和FireFox 1.5-3中需要大约3ms才能读取clientWidth属性...在IE8中需要超过200ms且更长时间表格中的单元格数量增加了.

这是一个已知的错误 ?有什么工作或解决方案吗?

Dea*_*rds 6

如果你还有兴趣,我已经解决了这个问题.解决方案非常复杂.基本上,您需要将一个简单的HTC附加到元素并缓存其clientWidth/Height.

简单的HTC看起来像这样:

<component lightweight="true">
<script>
window.clientWidth2[uniqueID]=clientWidth;
window.clientHeight2[uniqueID]=clientHeight;
</script>
</component>
Run Code Online (Sandbox Code Playgroud)

您需要使用CSS附加HTC:

.my-table td {behavior: url(simple.htc);}
Run Code Online (Sandbox Code Playgroud)

请记住,您只需要附加IE8的行为!

然后,您使用一些JavaScript为缓存的值创建getter:

var WIDTH = "clientWidth",
    HEIGHT = "clientHeight";

if (8 == document.documentMode) {

  window.clientWidth2 = {};
  Object.defineProperty(Element.prototype, "clientWidth2", {
    get: function() {
      return window.clientWidth2[this.uniqueID] || this.clientWidth;
    }
  });

  window.clientHeight2 = {};
  Object.defineProperty(Element.prototype, "clientHeight2", {
    get: function() {
      return window.clientHeight2[this.uniqueID] || this.clientHeight;
    }
  });

  WIDTH = "clientWidth2";
  HEIGHT = "clientHeight2";
}
Run Code Online (Sandbox Code Playgroud)

请注意,我创建了常量WIDTH/HEIGHT.您应该使用它们来获取元素的宽度/高度:

var width = element[WIDTH];
Run Code Online (Sandbox Code Playgroud)

这很复杂但很有效.我遇到了和你一样的问题,访问clientWidth非常慢.这很好地解决了这个问题.它仍然没有IE7那么快,但它又恢复了可用性.


Jos*_*osh 2

我无法找到任何文档表明这是一个已知的错误。为了提高性能,为什么不缓存 clientWidth 属性并定期更新缓存呢?IE 如果你的代码是:

var someValue = someElement.clientWidth + somethingElse;
Run Code Online (Sandbox Code Playgroud)

将其更改为:

// Note the following 3 lines use prototype
// To do this without prototype, create the function,
// create a closure out of it, and have the function
// repeatedly call itself using setTimeout() with a timeout of 1000
// milliseconds (or more/less depending on performance you need)
var updateCache = function() {
   this. clientWidthCache = $('someElement').clientWidth;
};
new PeriodicalExecuter(updateCache.bind(this),1);

var someValue = this.clientWidthCache + somethingElse
Run Code Online (Sandbox Code Playgroud)