1

最大 60 行、最大 50 列の html テーブルを表示するという確固たるビジネス要件を持つアプリケーションに取り組んでいます。

理想的には、ユーザーが個々のテーブル セルを選択するか、クリック アンド ドラッグして複数のセルを選択できるようにします。

私の問題は、現時点では IE6 の使用に制限されていることです。パフォーマンスを大幅に低下させることなく、このような多くのセルでこの種の選択を可能にする方法を見つける (またはコーディングする) のに本当に苦労しています。

私の現在の方法は、基本的に次のようになります。

$(document).ready(function() {
    var selecting = false;
    var colStart, rowStart;

    var tableContainer = $("#tableContainer")

    tableContainer.delegate("td", "mousedown", function() {
        //Clear Selection
        tableContainer.find("td.selected").removeClass("selected");

        $(this).addClass("selected");
        colStart = $(this).index();
        rowStart = $(this).parents("tr").index();
        selecting = true;
    }).delegate("td", "mouseover", function() {
        if (selecting) {
            //Clear Selection
            tableContainer.find("td.selected").removeClass("selected");

            var theCell = $(this);

            // Get the row and column numbers of the current cell 
            var colEnd = theCell.index();
            var rowEnd = theCell.parents("tr").index();

            // Account for rowEnd being smaller than rowStart
            var rowSliceStart = Math.min(rowStart, rowEnd);
            var rowSliceEnd = Math.max(rowStart, rowEnd);

            tableContainer.find("tr").slice(rowSliceStart, rowSliceEnd + 1).each(function() {
                var colSliceStart = Math.min(colStart, colEnd);
                var colSliceEnd = Math.max(colStart, colEnd);

                // Add the required class to the children
                $(this).children().slice(colSliceStart, colSliceEnd + 1).addClass("selected");
            });
        }
    }).delegate("td", "mouseup", function() {
        selecting = false;
    });
});​

この関数のパフォーマンスを改善する方法について何か提案はありますか? クラスの追加/削除がパフォーマンスのオーバーヘッドのほとんどを占めていると思うので、特に効率化を期待しています。

4

2 に答える 2

2
  1. 特にテーブルにたくさんのものが含まれている場合、テーブルはそれ自体がオーバーヘッドです。テーブルも、完成した場合にのみレンダリングされます。可能であれば、ページネーションを検討してください。

  2. 一定の DOM 操作、再描画 (外観の変更)、およびリフロー (寸法の変更) もオーバーヘッドです。

  3. IE6 自体は、重い JS 操作を実行するように構築されていません。IE6とは?10歳?10年前のJSとは?検証とポップアップですよね?

  4. 関数呼び出しの繰り返し。$(this)jQuery では、繰り返し呼び出すのではなく、関数呼び出しの値をキャッシュすることをお勧めします。

  5. あなたのコードで私が理解しているように、$.each()マウスオーバー中に 、スライス、およびいくつかのランダムな計算を実行しています。それは重い。

  6. 新しいjQueryの使用を検討してください

また、私はあなたのコードを少しきれいにしました:

$(function() {
    var selecting = false,
        tableContainer = $("#tableContainer"),
        colStart, rowStart;

    tableContainer.on("mousedown", 'td', function() {
        var $this = $(this); //reference this
        colStart = $this.index();
        rowStart = $this.closest("tr").index(); //use closest instead of parents to avoid going up to root
        $(".selected", tableContainer).removeClass("selected"); //context instead of find
        $this.addClass("selected");

        selecting = true;
    }).on("mouseover", 'td', function() {
        if (selecting) {

            var theCell = $(this),
                colEnd = theCell.index(),
                rowEnd = theCell.closest("tr").index(), //use closest
                rowSliceStart = Math.min(rowStart, rowEnd),
                rowSliceEnd = Math.max(rowStart, rowEnd);

            $(".selected", tableContainer).removeClass("selected");

            $("tr", tableContainer).slice(rowSliceStart, rowSliceEnd + 1).each(function() {
                var colSliceStart = Math.min(colStart, colEnd),
                    colSliceEnd = Math.max(colStart, colEnd);
                $('> *', this).slice(colSliceStart, colSliceEnd + 1).addClass("selected"); //using selector to get children instead of $(this).children()
            });
        }
    }).on("mouseup", 'td', function() {
        selecting = false;
    });
});​
于 2012-05-07T07:10:43.817 に答える
1

実際にはそれほど悪くはありません。頭のてっぺんから考えられる唯一のことは、マウスオーバーのデルタだけを計算することです。つまり、前の開始と終了の列/行を保存し、次のマウスオーバー イベントで、変更された要素だけのクラスを更新します。

その他の些細なこと:

  • $(this)mousedown ハンドラーにキャッシュする
  • IE6 のこれについて 100% 確信があるわけではありませんが、セレクターを から に変更してみて.find('td.selected')ください.find('.selected')。最初の例では、確認する条件が 2 つあるのに対し、1 つだけです。最新のブラウザーでは、jQuery が を利用できるため、2 番目の方が確実getElementsByClassNameに高速になりますが、IE6 にはそれが存在しないため、誰が知っているでしょうか?
    • 特にセルのコンテンツにさらに DOM 要素が含まれている場合は、よりターゲットを絞ったセレクターを作成して実験することもできます。.find('> tr > .selected')
  • マウスオーバー ハンドラを抑制します。
于 2012-05-07T07:05:55.690 に答える