/* * jQuery TableFix plugin ver 1.0.1 * Copyright (c) 2010 Otchy * This source file is subject to the MIT license. * http://www.otchy.net/javascript/tablefix/ */ (function($){ $.fn.tablefix = function(options) { var sbwidth = scrollbarWidth(); return this.each(function(index){ // 処理継続の判定 var opts = $.extend({}, options); var baseTable = $(this); var withWidth = (opts.width > 0); var withHeight = (opts.height > 0); if (withWidth) { withWidth = (opts.width < baseTable.width()); } else { opts.width = baseTable.width(); } if (withHeight) { withHeight = (opts.height < baseTable.height()); } else { opts.height = baseTable.height(); } if (withWidth || withHeight) { if (withWidth) { opts.height -= sbwidth; } if (withHeight) { opts.width -= sbwidth; } } else { return; } // 外部 div の設定 baseTable.wrap("
"); var div = baseTable.parent(); div.css({position: "relative"}); // スクロール部オフセットの取得、tdにwidthとheightを固定 var fixRows = (opts.fixRows > 0) ? opts.fixRows : 0; var fixCols = (opts.fixCols > 0) ? opts.fixCols : 0; var offsetX = 0; var offsetY = 0; baseTable.find('tr').each(function(indexY) { var trThis = $(this); if(jQuery.browser.msie) { trThis.height(trThis.height() + 1); } else { trThis.height(trThis.height()); } trThis.find('td,th').each(function(indexX) { // 先頭の行 if (indexY <= fixRows) { var cell = $(this); if (indexY == fixRows && indexX == fixCols) { offsetX = cell.position().left; offsetY = cell.parent('tr').position().top; } cell.width(cell.width()); cell.height(cell.height()); } // 先頭の列 else if (indexX <= fixCols) { var cell = $(this); cell.width(cell.width()); cell.height(cell.height()); } else { return false; } }); }); // テーブルの分割と初期化 var bodyTable = baseTable.wrap(''); var rowTable = baseTable.shallowClone().removeAttr('id').wrap(''); var colTable = baseTable.shallowClone().removeAttr('id').wrap(''); var crossTable = baseTable.shallowClone().removeAttr('id').wrap(''); baseTable.find('tr').each(function(indexY) { var trThis = $(this); var trRow, trCol, trCross; if (indexY < fixRows) { trRow = trThis.shallowClone().removeAttr('id').appendTo(rowTable); trCross = trThis.shallowClone().removeAttr('id').appendTo(crossTable); } trThis.find('td,th').each(function(indexX) { var cell = $(this); // 先頭の行 if (indexY < fixRows) { // 同時に先頭の列 if (indexX < fixCols) { trCross.append(cell); } // 単なる先頭の行 else { trRow.append(cell); } } // 先頭の列 else if (indexX < fixCols) { if (!trCol) { trCol = trThis.shallowClone().removeAttr('id').appendTo(colTable); } trCol.append(cell); } else { return false; } }); if (indexY < fixRows) { trThis.remove(); } }); var crossDiv = crossTable.parent().css({position: "absolute", overflow: "hidden"}); var rowDiv = rowTable.parent().css({position: "absolute", overflow: "hidden"}); var colDiv = colTable.parent().css({position: "absolute", overflow: "hidden"}); var bodyDiv = bodyTable.parent().css({position: "absolute", overflow: "auto"}); // クリップ領域の設定 var bodyWidth = opts.width - offsetX; var bodyHeight = opts.height - offsetY; crossDiv .width(offsetX) .height(offsetY); crossTable.width(offsetX); rowDiv .width(bodyWidth) .height(offsetY) .css({left: offsetX + 'px'}); colDiv .width(offsetX) .height(bodyHeight) .css({top: offsetY + 'px'}); colTable.width(offsetX); bodyDiv .width(bodyWidth + (withHeight ? sbwidth : 0)) .height(bodyHeight + (withWidth ? sbwidth : 0)) .css({left: offsetX + 'px', top: offsetY + 'px'}); div.append(rowDiv).append(colDiv).append(crossDiv); // スクロール連動 bodyDiv.scroll(function() { rowDiv.scrollLeft(bodyDiv.scrollLeft()); colDiv.scrollTop(bodyDiv.scrollTop()); }); rowDiv.scroll(function() { bodyDiv.scrollLeft(rowDiv.scrollLeft()); }); colDiv.scroll(function() { bodyDiv.scrollLeft(colDiv.scrollLeft()); }); // 外部 div の設定 div .width(opts.width + (withHeight ? sbwidth : 0)) .height(opts.height + (withWidth ? sbwidth : 0)); }); } })(jQuery); jQuery.fn.extend({ shallowClone: function() { return this.map(function () { return jQuery.shallowClone(this); }); } }); jQuery.extend({ shallowClone: function(elem) { var clone; clone = elem.cloneNode(false); return clone; } }); // http://chris-spittles.co.uk/jquery-calculate-scrollbar-width/ function scrollbarWidth() { var $inner = jQuery('