JQuery固定表頭插件fixedtableheader源碼註釋

  

  在開發XX車站信息系統時,須要將大量數據顯示在一個巨大的表格內部,因爲表格是一個總體,沒法分頁,加之數據不少,超出一屏,爲了方便用戶,決定使用固定表頭的插件,通過測試,發現JQuery 插件:fixedtableheader能夠簡單方便的實現功能。javascript

它的使用很簡單,須要設置的參數也只需2個,很實用。php

  使用方法:css

 

 

//引入文件
<script type="mce-text/javascript" src="http://i.cnblogs.com/jquery.min.js"></script>
<script type="mce-text/javascript" src="http://i.cnblogs.com/jquery.fixedtableheader.min.js"><
//綁定表格,headerrowsize 後面的參數是綁定須要固定的表頭的行數
<script type="mce-text/javascript">
$(document).ready(function() { 
   $('.tbl').fixedtableheader({ 
     highlightrow: true, headerrowsize: 4
   }); 
}); 
</script>

 

 

  使用時,我發現js文件只有 4KB,我很好奇它是怎麼實現的,因而就有了下文。html

  大體原理是:建立一個絕對定位的table,只包含表頭。當表格被用戶拖動超出屏幕時,表頭表格顯示;表格正常顯示時,表頭表格隱藏。java

 

/* Copyright (c) 2009 Mustafa OZCAN (http://www.mustafaozcan.net)
   * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
   * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
   * Version: .0.2
   * Requires: jquery.1.3+
   */
  jQuery.fn.fixedtableheader = function(options) {
      var settings = jQuery.extend({            //jQuery.extend( target [, object1 ] [, objectN ] )
          headerrowsize: 1,                    //這是默認參數
         highlightrow: false,                
         highlightclass: "highlight"           
     },
     options);                                //用戶設置的參數
                                             //若是用戶設置參數,會覆蓋對應的默認參數
     this.each(function(i) {                    //處理每一個table(該插件使用class屬性綁定,會存在多個table)
         var $tbl = $(this);
         var $tblhfixed = $tbl.find("tr:lt(" + settings.headerrowsize + ")");    //找到要固定表頭tr
         var headerelement = "th";
         if ($tblhfixed.find(headerelement).length == 0) headerelement = "td";    //沒有th,默認td爲表頭單元格
         if ($tblhfixed.find(headerelement).length > 0) {                        //有th單元格
             $tblhfixed.find(headerelement).each(function() {            
                 $(this).css("width", $(this).width());                //設置表頭th寬度
             });
             var $clonedTable = $tbl.clone().empty();                //建立表頭表格,即一對完整的table標籤
             var tblwidth = GetTblWidth($tbl);
             $clonedTable.attr("id", "fixedtableheader" + i).css({    //設置懸浮表頭絕對定位的位置
                 "position": "fixed",                                
                 "top": "0",
                 "left": $tbl.offset().left                            //.offset(): 獲取表格的左邊距
             }).append($tblhfixed.clone()).width(tblwidth).hide().appendTo($("body"));    //將表頭插入table標籤中
             if (settings.highlightrow)                                                    //鼠標移太高亮
                 $("tr:gt(" + (settings.headerrowsize - 1) + ")", $tbl).hover(function() {
                     $(this).addClass(settings.highlightclass);
                 },
                 function() {
                     $(this).removeClass(settings.highlightclass);
             });
             $(window).scroll(function() {                            //當滾動條發生變化時觸發scroll事件                    
                 if (jQuery.browser.msie && jQuery.browser.version == "6.0") 		//IE6.0
    			$clonedTable.css({								  //
                     "position": "absolute",
                     "top": $(window).scrollTop(),
                     "left": $tbl.offset().left
                 });
                 else $clonedTable.css({
                     "position": "fixed",
                     "top": "0",
                     "left": $tbl.offset().left - $(window).scrollLeft()
                 })
                 var sctop = $(window).scrollTop();		//頁面滾動條向下滾動的高度,也即頁面被隱藏的高度
                 var elmtop = $tblhfixed.offset().top;	//此時原始表格距離瀏覽器客戶區頂端的高度
                 if (sctop > elmtop && sctop <= (elmtop + $tbl.height() - $tblhfixed.height())) 
					$clonedTable.show();			//原來的表頭被滾動的不可見而且表格主體還沒有被滾動出屏幕
                 else 
					$clonedTable.hide();			//
             });
             $(window).resize(function() {
                 if ($clonedTable.outerWidth() != $tbl.outerWidth()) {		//若懸浮表跟不上resize的變化
                     $tblhfixed.find(headerelement).each(function(index) {	//從新設置懸浮表頭clonedTable每一個th/td的寬度
                         var w = $(this).width();
                         $(this).css("width", w);
                         $clonedTable.find(headerelement).eq(index).css("width", w);
                     });
                     $clonedTable.width($tbl.outerWidth());					//設置懸浮表的寬度,注意這裏.width()和css('width')的區別
                 }
                 $clonedTable.css("left", $tbl.offset().left);				//jquery中offset是相對於瀏覽器客戶區的相對偏移
             });
         }
     });
     function GetTblWidth($tbl) {		//獲取元素寬度(包括padding和border)
         var tblwidth = $tbl.outerWidth();
         return tblwidth;
     }
 };


 

 

 

在註釋該代碼過程當中,一個很嚴重的疑惑產生了:jquery

JQuery的.width() 和 CSS width 貌似不統一,有很大區別!因此又細細深刻研究了一番,收穫詳見這裏瀏覽器

 

IE6不能使用position:fixed,具體見這裏app

 

後記:2014-06-17ide

其實這個根本就達不到所謂的「fixtableheader」的效果,由於它只是簡單的額把全部的表頭都固定在了瀏覽器客戶區的頂部,而非是table所在區域的頂部。測試

請看這個演示錯誤的Demo

相關文章
相關標籤/搜索