表头固定(利用jquery实现原理介绍)

  表头固定应该是一个用得比较多的功能,参考了网上几个例子,在几个常用浏览器下显示不是很完美。而且很多都是基于固定的表格,在编码时多写一个固定的表头,对于动态生成的不知道多少列的表格就无从下手。而且例子中大多只能满足限定高度的情况,如果限定宽度,出现横向滚动条就无能为力了。

  我的目的就是要像jquery-ui那样,找到页面上存在的表格,调用一个方法就可以实现固定表头的功能。趁着动手学习写jquery插件的机会,自己写了一个表头固定的插件。

  使用方式和jquery-ui中的插件一样,只需要一行代码 $('#table1').fixHeader({height:100});

  下列浏览器测试通过

  IE7 IE8 firefox16.0 chrome22.0

  目前已知IE9下列不能对齐,手头暂时没有IE9来调试,以后再想法解决。

  说明:

  1 需要jquery,开发测试用的jquery-1.8.2,其他版本应该不大

  2 表头部分的<tr>需要写在<thead>里

  3 不限定宽度情况下,自动适应表格宽度(假设滚动条宽度为20px,实际宽度为表格宽度+20px)

  4 支持多行表头固定

  5 通常表格所有列都显示,无横向滚动条,只需要竖向滚动条的功能。该插件支持限定宽度条件下的表头固定。

  6 限定宽度和高度的条件下固定表头显示时,表头固定功能无法单纯通过css来实现,需要通过js实现,会有轻微闪烁

  7 已经考虑table和th,td的border-width设置成不同值的情况

  8 已经考虑了表头中绑定的事件,原表头中绑定的事件仍然保留

  特别注意:IE浏览器下,一定要设置表格中td和th的border-width,否则无法正确设置列宽,表头和数据部分会错位

  使用方法:

  限定高度:$('#table1').fixHeader({height:100});

  限定高度和宽度:$('#table3').fixHeader({height:100,width:500});

  下面为完整代码

  

复制代码 代码如下:

  /*!

  * fixHeader 1.0.0

  * Copyright 2012 chokobo

  *

  * make table header fixed

  *

  * notice: set th,id border-width in IE

  *

  * tested browser: IE7 IE8 firefox16.0 chrome22.0

  */

  (function( $, undefined ) {

  $.fn.fixHeader = function(options){

  var defaults = {

  width: '',

  height: ''

  };

  options = $.extend({}, defaults, options);

  var elem = this;

  if(options.height == ''){

  return this;

  }

  var thead = elem.find('thead');

  var fixTable = elem.clone().empty().removeAttr('id');

  //set head default background-color

  if(fixTable.css('background-color') == 'transparent' || fixTable.css('background-color') == ''){

  fixTable.css('background-color', '#fff');

  }

  fixTable.css({

  'position': 'absolute',

  'top': '0px',

  'border-bottom': $('tr:eq(0)', thead).find('th:eq(0), td:eq(0)').css('border-bottom-width')

  });

  $('tr:eq(0)', thead).find('th, td').each(function(){

  var col = $(this);

  if($.browser.mozilla){

  col.width(col.width());

  }

  else if($.browser.chrome){

  var colBorderWidth = parseInt(col.css('border-width'));

  col.width(col.width()+colBorderWidth);

  }

  else if($.browser.msie){

  var colBorderWidth = parseInt(col.css('border-width'));

  if(colBorderWidth){

  col.width(col.width()+colBorderWidth+colBorderWidth/2);//IE7??

  }

  }

  });

  //make head

  var dummyHead = thead.clone();

  thead.appendTo(fixTable);

  dummyHead.prependTo(elem);

  var tbodyWrapper = elem.wrap('<div class="body-wrapper"></div>').parent();

  var tableWrapper = tbodyWrapper.wrap('<div class="table-wrapper" style="position:relative;"/>').parent();

  setTableWidth();

  setWrapperSize();

  fixTable.prependTo(tableWrapper);

  return this;

  function setTableWidth(){

  if($.browser.mozilla){

  elem.width(elem.width());

  fixTable.css('width',elem.css('width'));

  }

  else if($.browser.chrome){

  elem.width(elem.outerWidth());

  fixTable.width(elem.outerWidth());

  }

  else if($.browser.msie){

  elem.width(elem.outerWidth());

  fixTable.width(elem.outerWidth());

  }

  else{

  elem.width(elem.outerWidth());

  fixTable.width(elem.outerWidth());

  }

  }

  function setWrapperSize(){

  var elemWidth = elem.outerWidth(true);

  var elemHeight = elem.outerHeight(true);

  var scrollBarWidth = 20;

  if(options.width == ''){

  tbodyWrapper.css({

  'width': (elemWidth+scrollBarWidth) + 'px',

  'height': options.height,

  'overflow-x': 'hidden',

  'overflow-y': 'auto'

  });

  }

  else{

  if(elemWidth <= options.width){

  tbodyWrapper.css({

  'width': options.width+'px',

  'height': options.height,

  'overflow-x': 'hidden',

  'overflow-y': 'auto'

  });

  }

  else{

  tableWrapper.css({

  'width': options.width,

  'height': options.height,

  'overflow': 'auto'

  });

  tableWrapper.scroll(function(){

  fixTable.css('top',tableWrapper.scrollTop()+'px');

  });

  }

  }

  }

  };

  })( jQuery );

  

复制代码 代码如下:

  /*

  功能:固定表頭。

  使用容器的ID進行設定$("#div").chromatable({width: "100%",height: "100%", scrolling: "yes"})

  table必須包含有<thead>標籤

  參數:無。

  */

  (function($){

  $.chromatable = {

  defaults: {

  width: "900px", //設定容器寬度,待擴展程式

  height: "300px", //設定容器高度,待擴展程式

  scrolling: "yes" //yes跟隨IE滾動條而滑動, no固定在頁面上僅容器滾動條滑動

  }

  };

  $.fn.chromatable = function(options){

  var options = $.extend({}, $.chromatable.defaults, options);

  return this.each(function(){

  var $divObj = $(this);

  var $tableObj = $divObj.find("table");

  var $uniqueID = $tableObj.attr("ID") + ("wrapper");

  var $class = $tableObj.attr("class");

  var $tableWidth = $tableObj.width();

  var top = $("#"+$tableObj.attr("ID")).offset().top;

  var left = $("#"+$tableObj.attr("ID")).offset().left

  $divObj.append("<table class='"+$class+"' id='"+$uniqueID+"' style='position:absolute;top:" +top+"px;left:"+left+"px;' width='"+$tableWidth+"' border='0' cellspacing='0' cellpadding='0'><thead>"+$("#"+$tableObj.attr("ID")).find("thead").html()+"</thead></table>");

  $.each($("#"+$tableObj.attr("ID")).find("thead th"), function(i,item){

  $("#"+$uniqueID).find("thead th").eq(i).width($(item).width());

  $(item).width($(item).width());

  });

  if(options.scrolling === "yes")

  {

  scrollEvent($tableObj.attr("ID"), $uniqueID);

  }

  resizeEvent($tableObj.attr("ID"), $uniqueID);

  });

  function scrollEvent(tableId, uniqueID)

  {

  var element = $("#"+uniqueID);

  $(window).scroll(function(){

  var top = $("#"+tableId).offset().top;

  var scrolls = $(this).scrollTop();

  if (scrolls > top) {

  if (window.XMLHttpRequest) {

  element.css({

  position: "fixed",

  top: 0

  });

  } else {

  element.css({

  top: scrolls

  });

  }

  }else {

  element.css({

  position: "absolute",

  top: top

  });

  }

  });

  };

  function resizeEvent(tableId, uniqueID)

  {

  var element = $("#"+uniqueID);

  $(window).resize(function(){

  var top = $("#"+tableId).offset().top;

  var scrolls = $(this).scrollTop();

  if (scrolls > top) {

  if (window.XMLHttpRequest) {

  element.css({

  position: "fixed",

  top: 0

  });

  } else {

  element.css({

  top: scrolls

  });

  }

  }else {

  element.css({

  position: "absolute",

  top: top

  });

  }

  });

  }

  };

  })(jQuery);