Excelで見かけるはじめの列を固定させたTableをjQueryで実現してみる
Excelやスプレッドシートのテーブルなどで、
列が多い場合にはじめの列を固定させて表示されているのを度々見かけますが、
このテーブルがレスポンシブで使えそうだと思いましたので、
jQueryを使って実現してみました。
↓作ってみたもののDEMO
方法
以下の様な手順で実現しました。
- テーブルをdiv要素で囲み、めいいっぱいに広げて、テーブルをwidth:autoで無理のない大きさに広げ、基準の大きさとして取得する
- 広げていたdiv要素を元の大きさに戻して、overflow: autoを設定
- さらにその要素をdiv要素で囲み、position:relativeを設定して、場所の基準とする。
- テーブルのはじめの列それぞれについて、CSSの情報を取得する
- テーブルのはじめの列がある位置にdisplay: table-cellおよびdisplay: tableに設定したdivでCSSをそのまま写した要素をdisplay: abosluteで配置する
以下が、その具体的なコードです。
FirefoxやIEでは、tableのCSSの取得に若干癖があり、苦労しましたが、
なんとかできました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | $(function() { var $targetTable = $(".fixedColumnTable"), //テーブル要素 tableWidth = 0; //tableをスクロールさせる要素と、位置の基準となる要素で囲む $targetTable.wrap("<div class='fixedColumnTableWrappper'></div>"); var $tableWrapper = $(".fixedColumnTableWrappper"); $tableWrapper .css({ "width": "9999px", "overflow": "auto" }); $tableWrapper.wrap("<div class='fixedColumnTableBase'></div>"); var $tableBase = $(".fixedColumnTableBase"); $tableBase .css({ "position": "relative" }); //親の要素をめいいっぱいに広げた状態で、tableをwidth: autoにすることでテーブルの自然な横幅を取得 $targetTable .css("width", "auto"); tableWidth = $targetTable.outerWidth(); $targetTable.css({ "width": tableWidth + "px", "min-width": tableWidth + "px" }); $tableWrapper.css("width", "auto"); //固定する列のcell一つずつについて実行 $targetTable.find("th:first-child, td:first-child").each(function(index) { var $targetCell = $(this), //テーブルのスタイルを取得 $targetCellStyles = { "display": "table", "width": ($targetCell.outerWidth() + 1) + "px", "height": $targetCell.outerHeight() + "px", "padding": $targetCell.css("padding"), "background-image": $targetCell.css("background-image"), "font": $targetCell.css("font"), "text-align": $targetCell.css("text-align"), "position": "absolute", "left": "0", "top": $targetCell.offset().top - $tableWrapper.offset().top, "z-index": 1 } //firefox, IEではtable-cellのborderが取得できないので、一旦tableのdisplayをblockに設定して取得 $targetTable.css("display", "block"); $targetCell.parent().css("display", "block"); $targetCell.css("display", "block"); $targetCellStyles["border-top-color"] = $targetCell.css("border-top-color"); $targetCellStyles["border-top-style"] = $targetCell.css("border-top-style"); $targetCellStyles["border-top-width"] = $targetCell.css("border-top-width"); $targetCellStyles["border-right-color"] = $targetCell.css("border-right-color"); $targetCellStyles["border-right-style"] = $targetCell.css("border-right-style"); $targetCellStyles["border-right-width"] = $targetCell.css("border-right-width"); $targetCellStyles["border-left-color"] = $targetCell.css("border-left-color"); $targetCellStyles["border-left-style"] = $targetCell.css("border-left-style"); $targetCellStyles["border-left-width"] = $targetCell.css("border-left-width"); //tableのスタイルを戻す $targetTable.css("display", "table"); $targetCell.parent().css("display", "table-row"); $targetCell.css({ "display": "table-cell", "visiblity": "hidden" }); if($targetCell.parent("thead tr:first-child").size() > 0) { $targetCellStyles["border-bottom-color"] = $targetCell.css("border-bottom-color"); $targetCellStyles["border-bottom-style"] = $targetCell.css("border-bottom-style"); $targetCellStyles["border-bottom-width"] = $targetCell.css("border-bottom-width"); $targetCellStyles["z-index"] = 2; } if($targetCell.parent("tbody tr:first-child").size() > 0) { $targetCellStyles["border-top"] = "none"; } if($targetCell.parent("tbody tr:last-child").size() > 0) { $targetCellStyles["border-bottom-color"] = $targetCell.css("border-bottom-color"); $targetCellStyles["border-bottom-style"] = $targetCell.css("border-bottom-style"); $targetCellStyles["border-bottom-width"] = $targetCell.css("border-bottom-width"); } //固定させるcellのスタイルをコピーした要素を、cellの位置に配置する $tableWrapper.append("<div class='fixedColumnCell" + index + "'></div>"); $(".fixedColumnCell" + index) .append("<div style='display:table-cell; vertical-align: middle;'></div>") .css($targetCellStyles); $(".fixedColumnCell" + index).find("div") .html($targetCell.html()); }); }); |
Author Profile
NINOMIYA
Webデザイナー兼コーダー出身のフロントエンド開発者です。 UXデザインやチーム開発の効率化など、勉強中です。
SHARE