jQueryのjQuery.exTable.jsという「テーブルのヘッダとフッタを固定する簡易プラグイン」をVisualforceページのapex:pageBlockTableに組み込んだときのメモです。

Step.1 静的リソースを追加してVisualforceページでインクルード
<apex:includeScript value="{!$Resource.jquery}"/>
<apex:includeScript value="{!$Resource.jQueryExTable}"/>
※リソース名は適当に・・・
Step.2 テーブルのヘッダを固定するJavaScript関数をVisualforceページに記載
<script type="text/javascript">
function setHeaderFixTable() {
    jQuery( 'table.HeaderFixTable' ).exTable({
    	height : 300,
        onInit : function(api){
            api.getContainer().css({
            	width:'100%'
            });
            api.getHeadTable().css({
            	width:'100%'
            });
            api.getHeadTable().find( 'th, td' ).css({
                'text-align':'center'
            });
        }
    });
}
</script>
※連想配列で初期化の設定が可能なので、これまた適当に・・・
Step.3 apex:pageBlockTableのstyleClass属性を設定
<apex:pageBlockTable ・・・ styleClass="HeaderFixTable">
※class名にHeaderFixTableを追加することでthead固定の処理が適用されるしくみ
Step.4 ページが読み込み完了されたタイミングで動くようにVisualforceページに記載
<script type="text/javascript">
	jQuery(window).load(function(){
		setHeaderFixTable();
	});
</script>

これで、tableタグのtheadが固定されました。ありがたいアドオンです。

ちなみに、アドオン自体のソースは参考サイトに記載されていたソースをコピー&ペーストして利用しました。ダウンロードのzipから取り出したソースではうまく動かなかった。。。

(function($){
    $.ex = $.ex || {};

    $.ex.table = function(idx , targets , option){
        var o = this,
        c = o.config = $.extend({} , $.ex.table.defaults , option);

        //処理対象となった要素を保持
        c.targets = targets;
        c.target = c.targets.eq(idx);
        c.index = idx;

        //新設するウィジェットの外枠を生成
        c.container = $('<div class="ex-table-container">' +
            '<div class="ex-table-head"><table/></div>' +
            '<div class="ex-table-body"></div>' +
            '<div class="ex-table-foot"><table/></div>' +
            '</div>');

        //ウィジェットのヘッダ、ボディ、フッタ枠の取得と幅調整
        c.head = c.container.find('> div.ex-table-head').css({
            'padding-right':c.scrollbarWidth
        });
        c.foot = c.container.find('> div.ex-table-foot').css({
            'padding-right':c.scrollbarWidth
        });
        c.headTable = c.head.find('> table');
        c.footTable = c.foot.find('> table');
        c.body = c.container.find('> div.ex-table-body').css({
            'overflow-x' : 'hidden',
            'overflow-y' : 'scroll',
            height : c.height
        });

        //処理対象テーブルの thead / tbody / tfoot の取得
        var thead = c.target.find('> thead')
            ,tfoot = c.target.find('> tfoot')
            ,tbody = c.target.find('> tbody');

        //幅を固定する
        o._fixedWidth(thead);
        o._fixedWidth(tfoot);
        o._fixedWidth(tbody);
        c.container.width(c.target.width() + c.scrollbarWidth + 1);
        
        //新設するウィジェットの外枠をページに挿入
        c.target.after(c.container);
        
        //ウィジェットのヘッダ、フッタ枠に thead と tfoot を挿入
        c.target.find('> thead').appendTo(c.head.find('> table'));
        c.target.find('> tfoot').appendTo(c.foot.find('> table'));
        c.target.appendTo(c.body);

        //テーブル要素の margin をクリア、table-layout でレイアウトを固定化
        $([c.target[0],c.headTable[0],c.footTable[0]]).css({
            'table-layout':'fixed',
            'margin':0
        });
    
        //初期化時のコールバック関数の実行
        if( c.onInit ){
            c.onInit.apply( c.targets , [ o ] );
        }
    }
    $.extend($.ex.table.prototype,{
        _fixedWidth : function(stack){
            var cols = stack.find('> tr:eq(0) > *');
            cols.each(function( idx ){
                var col = cols.eq(idx);
                col.width(col.width()).css('overflow','hidden');
            });
        },
        getIndex : function(){
            return this.config.index;
        },
        getTargets : function(){
            return this.config.targets;
        },
        getTarget: function(){
            return this.config.target;
        },
        getContainer : function(){
            return this.config.container;
        },
        getHead : function(){
            return this.config.head;
        },
        getHeadTable : function(){
            return this.config.headTable;
        },
        getBody : function(){
            return this.config.body;
        },
        getBodyTable: function(){
            return this.config.target;
        },
        getFoot : function(){
            return this.config.foot;
        },
        getFootTable : function(){
            return this.config.footTable;
        }
    });
    
    $.ex.table.defaults = {
        scrollbarWidth :16,
        height : 200,
        onInit : null
    }
    $.fn.exTable = function(option){
        var targets = this;
        return targets.each(function(idx){
            targets.eq(idx).data(
                'ex-table',
                new $.ex.table(idx,targets,option)
            );
        });
    }
})(jQuery);