【问题标题】:jquery/javascript how to calculate width fasterjquery/javascript如何更快地计算宽度
【发布时间】:2012-07-11 17:00:08
【问题描述】:

我有一个有 100 列的表。我正在循环遍历所有 th 元素,以明确设置每个 th 的宽度。

var $ths = $("table th");
$ths.each(function (i, th) {
    var $th = $(th);
    var width = $th.width();
    $th.width(width);
});

对于 100 列,这需要太多时间(超过 60 秒)。每个“获取宽度”调用需要 500-700 毫秒。这是因为它每次都需要生成布局,我得到了宽度。

问题 - 有没有更快的方法来获得宽度?

原因 - 我正在冻结标题。为此,我需要将每个标题的宽度设置为固定像素宽度。一切都是动态的,不能以 px 为单位预先设置每列的宽度。

【问题讨论】:

  • 为什么你不能用 CSS 做这个?
  • 您可以通过使用标准的for 循环并通过设置$th.width($th.width()); 取消width 变量来获得微小的改进。关于将标题行复制到另一个visibility:hidden 表并从该表中获取宽度,我有一种半生不熟的想法——也许这会更快,因为您将从单行表中获取宽度。我很惊讶 getting 宽度比 setting 宽度要长得多。
  • 您能解释一下“冻结标头”是什么意思吗?这是否意味着给定列中的任何内容都不能超过其标题的宽度?
  • @Blender 你会如何使用 CSS 来做到这一点?
  • 我对你的代码中的鼻涕进行了负载测试,它的运行速度与你使用 jQuery 运行的速度一样快。

标签: javascript jquery performance width


【解决方案1】:

您可以考虑为此编写普通的 javascript。可能会节省几毫秒的时间。

var cells = myTable.rows[0].children;

for ( var i = 0; i < cells.length; i++ ){
   cells[i].style.width = cells[i].offsetWidth + "px";
}

因为您使用的是 offsetWidth,you're not going to be able to get away from reflow。但是,根据 TH 中的字符数(假设文本不换行并且您使用的是固定的单一字体)和creatively applying CSS can greatly reduce reflow latency 来估计单元格宽度。

// Appends CSS Classes to stylesheet in doc head
function appendStyle(styles) {
  var css = document.createElement('style');
  css.type = 'text/css';

  // Browser compatibility check
  if (css.styleSheet) css.styleSheet.cssText = styles;
  else css.appendChild(document.createTextNode(styles));

  document.getElementsByTagName("head")[0].appendChild(css);
}

var cells       = myTable.rows[0].children;
var cellWidth   = 0;
var letterWidth = 5; // let's assume each letter is 5px wide
var classname   = '';
var styles      = '';

for ( var i = 0; i < cells.length; i++ ){
   classname         = "Cell" + i;
   cell[i].className = classname;
   cellWidth         = (letterWidth * cells[i].innerHTML.length);
   styles           += "." + classname + "{width:" + cellWidth + "px}";
} 

window.onload = function() { appendStyle(styles) };

您可以通过使用文档片段 (great writeup on performance benefits by John Resig) 来更进一步,方法是在运行时在 DOM 之外渲染整个内容,并在 DOM 加载后交换片段......但说真的,此时你'真的要问问自己,榨汁是否值得。

【讨论】:

  • 感谢您花时间回答。使用原生 js 并没有多大帮助。我的表格是在页面加载后动态创建的,所以之后我必须调用 appendStyles。近似假设每个字母的宽度来计算宽度的想法具有一定的潜力。我会试试看。冻结标头对于此企业应用程序的业务用户非常重要。我们正在使用同一页面动态创建数百个不同的视图(网格)。所有的努力都是值得的。
  • @Tejas:没问题。我真的很想知道你是如何解决这个问题的。解决后能否将您的解决方案发布为对问题的修改?
【解决方案2】:

您可以在设置宽度的地方分别为每列添加一个 onload 回调。这样,它不会在加载时发生循环,而不是循环。只是一个想法,但它可以工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    • 2011-01-08
    • 2019-06-23
    • 2014-11-21
    • 2017-10-21
    • 2018-09-13
    • 1970-01-01
    相关资源
    最近更新 更多