4

クラス「GridCell」のテーブルセル内のすべてのdivを通過するループがあります。これは、グリッドまたは列のサイズが変更された場合に発生する必要があります。

行と列の数を増やして、より多くの時間差を確認しました。現在、ループは約750ミリ秒です。

しかし、私が理解していないのは、「ループの一部」の方がはるかに高速であるということです。次の3つのループを参照してください。最初は遅いです。最初のループの一部のみを実行する2番目と3番目のループは非常に高速です。

//Around 750 ms
$('table.Grid tbody td.GridCell > div').each(function() {
    var width = $(this).parent().width();
    $(this).css('width', width - 3);
});

//Around 60 ms
$('table.Grid tbody td.GridCell > div').each(function() {
    var width = $(this).parent().width();
});

//Around 15 ms
$('table.Grid tbody td.GridCell > div').each(function() {
    $(this).css('width', 100);
});

つまり、1行はわずか60または15ミリ秒ですが、2つを合わせると750です。この違いは何ですか。

psループを実行する順序は関係ありません。最初のループは、そのループが最後に実行されたときも、常に他のループよりもはるかに遅くなります。

4

9 に答える 9

2

最初のループでは、計算された幅を計算し、それを反復ごとに別の要素に適用します。2番目のループでは、幅を計算し、それを変数に割り当てるだけです。そして3番目のループでは、静的なインラインスタイルを適用しているだけです。

私が言っているのは、最後の2つのループを組み合わせても、最初のループの機能と同じではないため、最初のループが他の2つのループよりも遅いのは当然のことです。

次のようなことを試してください。

var $divs = $('table.Grid tbody td.GridCell > div'),
    m = [];

// case 1
$divs.each(function() {
    var width = $(this).parent().width();
    $(this).css('width', width - 3);
});

// case 2
$divs.each(function() {
    m.push( $(this).parent().width() );
}).each(function(i) {
    $(this).css('width', m[i] - 3);
});

ここで簡単なパフォーマンステストを行いました:http://jsperf.com/tablewidthそして違いは非常に小さいようです。

于 2012-08-29T08:53:04.920 に答える
2
// collect the widths from the first row only
var widths = $('table.Grid tbody tr:first-child td.GridCell').map(function(idx) {
  return $(this).width() - 3;

  // or use:
  // return this.clientWidth - 3;
  // if you're not targeting IE <= 7
});

// apply the widths to each div
$('table.Grid tbody td.GridCell > div').each(function(idx) {
  this.style.width = widths[idx % widths.length] + 'px';
});
于 2012-08-29T09:30:21.287 に答える
1
var $rows = $('table.Grid tbody').children('tr');

// we only need the widths from the first row
var widths = $rows.first().children('td').map(function() {
    return $(this).width() - 3;
}).get();

// process each row individually
$rows.each(function() {
    $('td.gridCell > div', this).css('width', function(i) {
         return widths[i];
    });
});
于 2012-08-29T09:15:05.543 に答える
0

最初の例では

$('table.Grid tbody td.GridCell > div').each(function() {
    var width = $(this).parent().width();
    $(this).css('width', width - 3);
});

あなたは$(this)二度評価しています。代わりに書いてみてください

$('table.Grid tbody td.GridCell > div').each(function() {
    var $this = $(this);
    var width = $this.parent().width();
    $this.css('width', width - 3);
});

またさらに良い(編集:わからないeach())メソッドに渡された現在の要素も使用してみてください

$('table.Grid tbody td.GridCell > div').each(function(i, el) {
    var $this = $(el);
    var width = $this.parent().width();
    $this.css('width', width - 3);
});
于 2012-08-29T08:52:55.367 に答える
0

使用した場合はどうなりますか

$('table.Grid tbody td.GridCell > div').each(function(i,domEle) {
    $(domEle).css('width', $(domEle).parent().width() - 3);
});

また、jQueryで最適化セレクターを使用してみてください

于 2012-08-29T08:53:16.997 に答える
0

親の幅の計算が動的ではなく(子のサイズ変更が親に影響を与える)、幅が一定である(の場合は大きい)と仮定します。

var width = $(this).parent().width();

$('table.Grid tbody td.GridCell > div').each(function() {
    $(this).css('width', width - 3);
});
于 2012-08-29T08:55:41.683 に答える
0

正確な詳細を言うのは難しいですが、私はこの問題を次のように理解しています:

var width = $(this).parent().width();-これを呼び出すと、ブラウザは選択された要素の実際の寸法を取得するように強制されます。 $(this).css('width', 100);-これにより、ブラウザはドキュメントをリフローします。したがって、この行を実行すると、ブラウザはページの一部を再計算する必要があります。

なぜ最初は他の2つのループよりも遅く動作するのですか?あなたがそれだけをするとき、var width = $(this).parent().width();それは一度すべての幅を計算して、それらをキャッシュから与えることができるように私はそれを見る。この行だけを実行すると、$(this).css('width', 100);ブラウザはスクリプトが実行されるまで待機できます。そして、すべての更新要素を一度に再描画します。ただし、最初のループを実行すると、一部の要素を更新するよりも、ブラウザに幅の計算を強制します。Dimentionsキャッシュが壊れています。ここでも幅を取得したいので、ブラウザはページを再描画する必要があります。したがって、各サイクルで、他の2つのループとは反対に、1回しか実行できないときにページを再描画します。

于 2012-08-29T09:07:58.193 に答える
0

これはJSの問題である必要はありません!ループを忘れてください。目的の機能を実現するためにJS/jQueryを使用する必要はまったくありません。

の子divが、.GridCell使用可能なすべての幅から3pxを引いたものになるようにするには、次のCSSルールを使用できます。

.GridCell>div {
  width:auto;             /*take up all available width (for block elements)*/
  margin:0 1.5px;         /*add a 1.5px buffer on both sides of the div*/
}

あなたが本当に派手になりたいと思っていて、ブラウザの互換性マトリックスがやや貧弱であることを気にしないのであれば、CSS3に頼ることができますcalc()

.GridCell>div {
  width:calc(100% - 3px); /*look up vendor-specific prefixes of the property
                            if you want for this to work on more browsers*/
  margin: 0 auto;         /*now that the width is calculated correctly above,
                            center the div. Or don't!*/
}

出来上がり

于 2012-08-29T09:24:01.577 に答える
0

OK、ここに別の選択肢があります:

$('table.Grid tbody td.GridCell > div').css('width', function() {
    return $(this.parentNode).width() - 3;
});
于 2012-08-29T09:46:27.703 に答える