2012-05-07 11 views
1

私は、最大60行50列までのhtmlテーブルを表示するためのビジネス要件が厳しいアプリケーションに取り組んでいます。大規模なテーブルで高性能の選択可能なセル - IE6

理想的には、ユーザーは個々の表のセルを選択するか、クリックしてドラッグして複数のセルを選択することができます。

私の悩みは、現時点で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; 
    }); 
});​ 

誰もが、この機能のパフォーマンスを改善するための方法について何か提案がありますか?私は、クラスの追加/削除がパフォーマンス上のオーバーヘッドの大半を占めていると考えています。だから私は特にそこで効率を見つけることを望んでいます。

答えて

2
  1. の表は、オーバーヘッドそのものです。テーブルは、完了したときにのみレンダリングされます。可能であればページ区切りを検討してください。

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

  3. IE6自体は、重いJS操作を行うために構築されていませんでした。 IE6は何ですか? 10歳? JSは何10年前ですか?検証とポップアップが正しいでしょうか?

  4. 繰り返しの関数呼び出し。 jQueryでは、繰り返し呼び出すのではなく、$(this)のような関数呼び出しの値をキャッシュするのが最善です。

  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; 
    }); 
});​ 
+0

ニース。多分、選択されたセルのリストをキャッシュして、各マウスオーバーハンドラの呼び出し間でそれらを再度見つける必要を避けることができますか? – Ben

+0

'$(" tr "、tableContainer)' – Ben

+0

@Benはいのキャッシュを保持することもできますが、キャッシュすることは難しいですが、それは難しいですが、それを構築するにはOPまでです。しかし、ガベージコレクションの問題があります。 DOMで要素が削除されると、その要素に対応するキャッシュエントリも手動でゼロにする必要があります。そうしないと、メモリリークが発生します。 – Joseph

1

実際にはあまりにも悪くはありません。私が頭の上から外すと思う唯一のことは、マウスオーバーでデルタを計算することです。つまり、以前の開始および終了列/行を格納し、次のmouseoverイベントで、変更された要素だけのクラスを更新します。

その他のマイナーなもの:マウスダウンハンドラ

    • キャッシュ$(this)私はIE6のために、この1約100%わからないんだけど、あなたは.find('td.selected')からわずか.find('.selected')にセレクタを変更してみてください可能性があります。最初のものには2つの条件があります。現代のブラウザでは、が速く、jQueryはgetElementsByClassNameを利用することができますが、それはIE6には存在しませんので、誰が知っていますか?
      • セルの内容にさらにDOM要素が含まれている場合は、さらにターゲット設定されたセレクタを試してみることもできます。 .find('> tr > .selected')
    • マウスオーバーハンドラを調整します。彼らはものがたくさん含まれている場合は特に
  • +0

    どうもありがとうございました。 addClass()メソッドが最もパフォーマンス上のオーバーヘッドを確実に抱えているので、デルタにアプローチする方法について考える必要があります。そのため、作業している要素の数を減らすことができれば助かります。私はマウスオーバーハンドラを絞ることによって何を意味するのか尋ねることができますか?タイムアウトを設定するようなものなので、ホバーに似ていますか?もしそうなら、どのように機能するかの例はありますか? – Alex

    +0

    @Alexここでは、絞り込み機能のためのjQプラグインがあります:http://benalman.com/projects/jquery-throttle-debounce-plugin/それは、マウスオーバーがあるたびにその関数が実行されないことを意味しますが、 Xミリ秒に1回。 – nickf

    +0

    すばらしいおかげだ!私は仕事に戻ったときに見てみましょう – Alex

    関連する問題