问题
I have a table with 100 columns. I'm running a loop through all the th elements, to explicitly set the width of each th.
var $ths = $("table th");
$ths.each(function (i, th) {
var $th = $(th);
var width = $th.width();
$th.width(width);
});
For 100 columns, this takes too much amount of time (more than 60s). Each "get width" call takes 500-700 ms. This is because it needs to generate layout every time, I get width.
Question - Is there a faster way to get width?
Reason - I'm freezing header. For that I need to set width of each header to fixed pixel width. Everything is dynamic and pre-setting the width of each column in px is not an option.
回答1:
You might consider writing plain vanilla javascript for this. Might shave some milliseconds off your time.
var cells = myTable.rows[0].children;
for ( var i = 0; i < cells.length; i++ ){
cells[i].style.width = cells[i].offsetWidth + "px";
}
Because you're using offsetWidth, you're not going to be able to get away from reflow. However, estimating the cell widths based on how many characters are in the TH (assuming the text doesn't wrap and you're using a fixed, monotyped font) and 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) };
You could take this even further by using document fragments (great writeup on performance benefits by John Resig) by rendering the whole things outside of the DOM at runtime and swapping the fragment in after the DOM is loaded...but seriously, at this point you've really got to ask yourself if the juice is worth the squeeze.
回答2:
You could add an onload callback to each column individually where you set up its width. This way, instead of in a loop it happens as they load. Just an idea, but it could work.
来源:https://stackoverflow.com/questions/11443451/jquery-javascript-how-to-calculate-width-faster