2014-09-25 122 views
1

我已经看到很多方法可以将标题固定在标准表上,但通常这涉及克隆表(以匹配变量宽度)。这当然不适合我,因为标题是可点击的,允许人们对特定行的内容进行排序。如何在滚动排序表时固定标题行

那么,有没有一种方法来实质上'冻结'标题行,同时仍然保留排序的功能?

下面是基本表的代码(所有的CSS保持在清洁“样式” &同样与JS)

var stIsIE = /*@[email protected]*/false; 
 

 
sorttable = { 
 
\t init: function() { 
 
    // quit if this function has already been called 
 
    if (arguments.callee.done) return; 
 
    // flag this function so we don't do the same thing twice 
 
    arguments.callee.done = true; 
 
    // kill the timer 
 
    if (_timer) clearInterval(_timer); 
 

 
    if (!document.createElement || !document.getElementsByTagName) return; 
 

 
    sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; 
 

 
    forEach(document.getElementsByTagName('table'), function(table) { 
 
     if (table.className.search(/\bsortable\b/) != -1) { 
 
     sorttable.makeSortable(table); 
 
     } 
 
    }); 
 

 
    }, 
 

 
    makeSortable: function(table) { 
 
    if (table.getElementsByTagName('thead').length == 0) { 
 
     // table doesn't have a tHead. Since it should have, create one and 
 
     // put the first table row in it. 
 
     the = document.createElement('thead'); 
 
     the.appendChild(table.rows[0]); 
 
     table.insertBefore(the,table.firstChild); 
 
    } 
 
    // Safari doesn't support table.tHead, sigh 
 
    if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; 
 

 
    if (table.tHead.rows.length != 1) return; // can't cope with two header rows 
 

 
    // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as 
 
    // "total" rows, for example). This is B&R, since what you're supposed 
 
    // to do is put them in a tfoot. So, if there are sortbottom rows, 
 
    // for backwards compatibility, move them to tfoot (creating it if needed). 
 
    sortbottomrows = []; 
 
    for (var i=0; i<table.rows.length; i++) { 
 
     if (table.rows[i].className.search(/\bsortbottom\b/) != -1) { 
 
     sortbottomrows[sortbottomrows.length] = table.rows[i]; 
 
     } 
 
    } 
 
    if (sortbottomrows) { 
 
     if (table.tFoot == null) { 
 
     // table doesn't have a tfoot. Create one. 
 
     tfo = document.createElement('tfoot'); 
 
     table.appendChild(tfo); 
 
     } 
 
     for (var i=0; i<sortbottomrows.length; i++) { 
 
     tfo.appendChild(sortbottomrows[i]); 
 
     } 
 
     delete sortbottomrows; 
 
    } 
 

 
    // work through each column and calculate its type 
 
    headrow = table.tHead.rows[0].cells; 
 
    for (var i=0; i<headrow.length; i++) { 
 
     // manually override the type with a sorttable_type attribute 
 
     if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col 
 
     mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/); 
 
     if (mtch) { override = mtch[1]; } 
 
\t  if (mtch && typeof sorttable["sort_"+override] == 'function') { 
 
\t   headrow[i].sorttable_sortfunction = sorttable["sort_"+override]; 
 
\t  } else { 
 
\t   headrow[i].sorttable_sortfunction = sorttable.guessType(table,i); 
 
\t  } 
 
\t  // make it clickable to sort 
 
\t  headrow[i].sorttable_columnindex = i; 
 
\t  headrow[i].sorttable_tbody = table.tBodies[0]; 
 
\t  dean_addEvent(headrow[i],"click", sorttable.innerSortFunction = function(e) { 
 

 
      if (this.className.search(/\bsorttable_sorted\b/) != -1) { 
 
      // if we're already sorted by this column, just 
 
      // reverse the table, which is quicker 
 
      sorttable.reverse(this.sorttable_tbody); 
 
      this.className = this.className.replace('sorttable_sorted', 
 
                'sorttable_sorted_reverse'); 
 
      this.removeChild(document.getElementById('sorttable_sortfwdind')); 
 
      sortrevind = document.createElement('span'); 
 
      sortrevind.id = "sorttable_sortrevind"; 
 
      sortrevind.innerHTML = stIsIE ? '&nbsp<font face="webdings">5</font>' : '&nbsp;&#x25B4;'; 
 
      this.appendChild(sortrevind); 
 
      return; 
 
      } 
 
      if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { 
 
      // if we're already sorted by this column in reverse, just 
 
      // re-reverse the table, which is quicker 
 
      sorttable.reverse(this.sorttable_tbody); 
 
      this.className = this.className.replace('sorttable_sorted_reverse', 
 
                'sorttable_sorted'); 
 
      this.removeChild(document.getElementById('sorttable_sortrevind')); 
 
      sortfwdind = document.createElement('span'); 
 
      sortfwdind.id = "sorttable_sortfwdind"; 
 
      sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;'; 
 
      this.appendChild(sortfwdind); 
 
      return; 
 
      } 
 

 
      // remove sorttable_sorted classes 
 
      theadrow = this.parentNode; 
 
      forEach(theadrow.childNodes, function(cell) { 
 
      if (cell.nodeType == 1) { // an element 
 
       cell.className = cell.className.replace('sorttable_sorted_reverse',''); 
 
       cell.className = cell.className.replace('sorttable_sorted',''); 
 
      } 
 
      }); 
 
      sortfwdind = document.getElementById('sorttable_sortfwdind'); 
 
      if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } 
 
      sortrevind = document.getElementById('sorttable_sortrevind'); 
 
      if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } 
 

 
      this.className += ' sorttable_sorted'; 
 
      sortfwdind = document.createElement('span'); 
 
      sortfwdind.id = "sorttable_sortfwdind"; 
 
      sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;'; 
 
      this.appendChild(sortfwdind); 
 

 
\t   // build an array to sort. This is a Schwartzian transform thing, 
 
\t   // i.e., we "decorate" each row with the actual sort key, 
 
\t   // sort based on the sort keys, and then put the rows back in order 
 
\t   // which is a lot faster because you only do getInnerText once per row 
 
\t   row_array = []; 
 
\t   col = this.sorttable_columnindex; 
 
\t   rows = this.sorttable_tbody.rows; 
 
\t   for (var j=0; j<rows.length; j++) { 
 
\t   row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]]; 
 
\t   } 
 
\t   /* If you want a stable sort, uncomment the following line */ 
 
\t   //sorttable.shaker_sort(row_array, this.sorttable_sortfunction); 
 
\t   /* and comment out this one */ 
 
\t   row_array.sort(this.sorttable_sortfunction); 
 

 
\t   tb = this.sorttable_tbody; 
 
\t   for (var j=0; j<row_array.length; j++) { 
 
\t   tb.appendChild(row_array[j][1]); 
 
\t   } 
 

 
\t   delete row_array; 
 
\t  }); 
 
\t  } 
 
    } 
 
    }, 
 

 
    guessType: function(table, column) { 
 
    // guess the type of a column based on its first non-blank row 
 
    sortfn = sorttable.sort_alpha; 
 
    for (var i=0; i<table.tBodies[0].rows.length; i++) { 
 
     text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]); 
 
     if (text != '') { 
 
     if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) { 
 
      return sorttable.sort_numeric; 
 
     } 
 
     // check for a date: dd/mm/yyyy or dd/mm/yy 
 
     // can have/or . or - as separator 
 
     // can be mm/dd as well 
 
     possdate = text.match(sorttable.DATE_RE) 
 
     if (possdate) { 
 
      // looks like a date 
 
      first = parseInt(possdate[1]); 
 
      second = parseInt(possdate[2]); 
 
      if (first > 12) { 
 
      // definitely dd/mm 
 
      return sorttable.sort_ddmm; 
 
      } else if (second > 12) { 
 
      return sorttable.sort_mmdd; 
 
      } else { 
 
      // looks like a date, but we can't tell which, so assume 
 
      // that it's dd/mm (English imperialism!) and keep looking 
 
      sortfn = sorttable.sort_ddmm; 
 
      } 
 
     } 
 
     } 
 
    } 
 
    return sortfn; 
 
    }, 
 

 
    getInnerText: function(node) { 
 
    // gets the text we want to use for sorting for a cell. 
 
    // strips leading and trailing whitespace. 
 
    // this is *not* a generic getInnerText function; it's special to sorttable. 
 
    // for example, you can override the cell text with a customkey attribute. 
 
    // it also gets .value for <input> fields. 
 

 
    if (!node) return ""; 
 

 
    hasInputs = (typeof node.getElementsByTagName == 'function') && 
 
       node.getElementsByTagName('input').length; 
 

 
    if (node.getAttribute("sorttable_customkey") != null) { 
 
     return node.getAttribute("sorttable_customkey"); 
 
    } 
 
    else if (typeof node.textContent != 'undefined' && !hasInputs) { 
 
     return node.textContent.replace(/^\s+|\s+$/g, ''); 
 
    } 
 
    else if (typeof node.innerText != 'undefined' && !hasInputs) { 
 
     return node.innerText.replace(/^\s+|\s+$/g, ''); 
 
    } 
 
    else if (typeof node.text != 'undefined' && !hasInputs) { 
 
     return node.text.replace(/^\s+|\s+$/g, ''); 
 
    } 
 
    else { 
 
     switch (node.nodeType) { 
 
     case 3: 
 
      if (node.nodeName.toLowerCase() == 'input') { 
 
      return node.value.replace(/^\s+|\s+$/g, ''); 
 
      } 
 
     case 4: 
 
      return node.nodeValue.replace(/^\s+|\s+$/g, ''); 
 
      break; 
 
     case 1: 
 
     case 11: 
 
      var innerText = ''; 
 
      for (var i = 0; i < node.childNodes.length; i++) { 
 
      innerText += sorttable.getInnerText(node.childNodes[i]); 
 
      } 
 
      return innerText.replace(/^\s+|\s+$/g, ''); 
 
      break; 
 
     default: 
 
      return ''; 
 
     } 
 
    } 
 
    }, 
 

 
    reverse: function(tbody) { 
 
    // reverse the rows in a tbody 
 
    newrows = []; 
 
    for (var i=0; i<tbody.rows.length; i++) { 
 
     newrows[newrows.length] = tbody.rows[i]; 
 
    } 
 
    for (var i=newrows.length-1; i>=0; i--) { 
 
     tbody.appendChild(newrows[i]); 
 
    } 
 
    delete newrows; 
 
    }, 
 

 
    /* sort functions 
 
    each sort function takes two parameters, a and b 
 
    you are comparing a[0] and b[0] */ 
 
    sort_numeric: function(a,b) { 
 
    aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); 
 
    if (isNaN(aa)) aa = 0; 
 
    bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); 
 
    if (isNaN(bb)) bb = 0; 
 
    return aa-bb; 
 
    }, 
 
sort_alpha: function(a,b) { 
 
    if (a[0].toLowerCase()==b[0].toLowerCase()) return 0; 
 
    if (a[0].toLowerCase()<b[0].toLowerCase()) return -1; 
 
    return 1; 
 
    }, 
 
    sort_ddmm: function(a,b) { 
 
    mtch = a[0].match(sorttable.DATE_RE); 
 
    y = mtch[3]; m = mtch[2]; d = mtch[1]; 
 
    if (m.length == 1) m = '0'+m; 
 
    if (d.length == 1) d = '0'+d; 
 
    dt1 = y+m+d; 
 
    mtch = b[0].match(sorttable.DATE_RE); 
 
    y = mtch[3]; m = mtch[2]; d = mtch[1]; 
 
    if (m.length == 1) m = '0'+m; 
 
    if (d.length == 1) d = '0'+d; 
 
    dt2 = y+m+d; 
 
    if (dt1==dt2) return 0; 
 
    if (dt1<dt2) return -1; 
 
    return 1; 
 
    }, 
 
    sort_mmdd: function(a,b) { 
 
    mtch = a[0].match(sorttable.DATE_RE); 
 
    y = mtch[3]; d = mtch[2]; m = mtch[1]; 
 
    if (m.length == 1) m = '0'+m; 
 
    if (d.length == 1) d = '0'+d; 
 
    dt1 = y+m+d; 
 
    mtch = b[0].match(sorttable.DATE_RE); 
 
    y = mtch[3]; d = mtch[2]; m = mtch[1]; 
 
    if (m.length == 1) m = '0'+m; 
 
    if (d.length == 1) d = '0'+d; 
 
    dt2 = y+m+d; 
 
    if (dt1==dt2) return 0; 
 
    if (dt1<dt2) return -1; 
 
    return 1; 
 
    }, 
 

 
    shaker_sort: function(list, comp_func) { 
 
    // A stable sort function to allow multi-level sorting of data 
 
    // see: http://en.wikipedia.org/wiki/Cocktail_sort 
 
    // thanks to Joseph Nahmias 
 
    var b = 0; 
 
    var t = list.length - 1; 
 
    var swap = true; 
 

 
    while(swap) { 
 
     swap = false; 
 
     for(var i = b; i < t; ++i) { 
 
      if (comp_func(list[i], list[i+1]) > 0) { 
 
       var q = list[i]; list[i] = list[i+1]; list[i+1] = q; 
 
       swap = true; 
 
      } 
 
     } // for 
 
     t--; 
 

 
     if (!swap) break; 
 

 
     for(var i = t; i > b; --i) { 
 
      if (comp_func(list[i], list[i-1]) < 0) { 
 
       var q = list[i]; list[i] = list[i-1]; list[i-1] = q; 
 
       swap = true; 
 
      } 
 
     } // for 
 
     b++; 
 

 
    } // while(swap) 
 
    } 
 
} 
 

 
/* ****************************************************************** 
 
    Supporting functions: bundled here to avoid depending on a library 
 
    ****************************************************************** */ 
 

 
// Dean Edwards/Matthias Miller/John Resig 
 

 
/* for Mozilla/Opera9 */ 
 
if (document.addEventListener) { 
 
    document.addEventListener("DOMContentLoaded", sorttable.init, false); 
 
} 
 

 
/* for Internet Explorer */ 
 
/*@cc_on @*/ 
 
/*@if (@_win32) 
 
    document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>"); 
 
    var script = document.getElementById("__ie_onload"); 
 
    script.onreadystatechange = function() { 
 
     if (this.readyState == "complete") { 
 
      sorttable.init(); // call the onload handler 
 
     } 
 
    }; 
 
/*@end @*/ 
 

 
/* for Safari */ 
 
if (/WebKit/i.test(navigator.userAgent)) { // sniff 
 
    var _timer = setInterval(function() { 
 
     if (/loaded|complete/.test(document.readyState)) { 
 
      sorttable.init(); // call the onload handler 
 
     } 
 
    }, 10); 
 
} 
 

 
/* for other browsers */ 
 
window.onload = sorttable.init; 
 

 
// written by Dean Edwards, 2005 
 
// with input from Tino Zijdel, Matthias Miller, Diego Perini 
 

 
// http://dean.edwards.name/weblog/2005/10/add-event/ 
 

 
function dean_addEvent(element, type, handler) { 
 
\t if (element.addEventListener) { 
 
\t \t element.addEventListener(type, handler, false); 
 
\t } else { 
 
\t \t // assign each event handler a unique ID 
 
\t \t if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++; 
 
\t \t // create a hash table of event types for the element 
 
\t \t if (!element.events) element.events = {}; 
 
\t \t // create a hash table of event handlers for each element/event pair 
 
\t \t var handlers = element.events[type]; 
 
\t \t if (!handlers) { 
 
\t \t \t handlers = element.events[type] = {}; 
 
\t \t \t // store the existing event handler (if there is one) 
 
\t \t \t if (element["on" + type]) { 
 
\t \t \t \t handlers[0] = element["on" + type]; 
 
\t \t \t } 
 
\t \t } 
 
\t \t // store the event handler in the hash table 
 
\t \t handlers[handler.$$guid] = handler; 
 
\t \t // assign a global event handler to do all the work 
 
\t \t element["on" + type] = handleEvent; 
 
\t } 
 
}; 
 
// a counter used to create unique IDs 
 
dean_addEvent.guid = 1; 
 

 
function removeEvent(element, type, handler) { 
 
\t if (element.removeEventListener) { 
 
\t \t element.removeEventListener(type, handler, false); 
 
\t } else { 
 
\t \t // delete the event handler from the hash table 
 
\t \t if (element.events && element.events[type]) { 
 
\t \t \t delete element.events[type][handler.$$guid]; 
 
\t \t } 
 
\t } 
 
}; 
 

 
function handleEvent(event) { 
 
\t var returnValue = true; 
 
\t // grab the event object (IE uses a global event object) 
 
\t event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event); 
 
\t // get a reference to the hash table of event handlers 
 
\t var handlers = this.events[event.type]; 
 
\t // execute each event handler 
 
\t for (var i in handlers) { 
 
\t \t this.$$handleEvent = handlers[i]; 
 
\t \t if (this.$$handleEvent(event) === false) { 
 
\t \t \t returnValue = false; 
 
\t \t } 
 
\t } 
 
\t return returnValue; 
 
}; 
 

 
function fixEvent(event) { 
 
\t // add W3C standard event methods 
 
\t event.preventDefault = fixEvent.preventDefault; 
 
\t event.stopPropagation = fixEvent.stopPropagation; 
 
\t return event; 
 
}; 
 
fixEvent.preventDefault = function() { 
 
\t this.returnValue = false; 
 
}; 
 
fixEvent.stopPropagation = function() { 
 
    this.cancelBubble = true; 
 
} 
 

 
// Dean's forEach: http://dean.edwards.name/base/forEach.js 
 
/* 
 
\t forEach, version 1.0 
 
\t Copyright 2006, Dean Edwards 
 
\t License: http://www.opensource.org/licenses/mit-license.php 
 
*/ 
 

 
// array-like enumeration 
 
if (!Array.forEach) { // mozilla already supports this 
 
\t Array.forEach = function(array, block, context) { 
 
\t \t for (var i = 0; i < array.length; i++) { 
 
\t \t \t block.call(context, array[i], i, array); 
 
\t \t } 
 
\t }; 
 
} 
 

 
// generic enumeration 
 
Function.prototype.forEach = function(object, block, context) { 
 
\t for (var key in object) { 
 
\t \t if (typeof this.prototype[key] == "undefined") { 
 
\t \t \t block.call(context, object[key], key, object); 
 
\t \t } 
 
\t } 
 
}; 
 

 
// character enumeration 
 
String.forEach = function(string, block, context) { 
 
\t Array.forEach(string.split(""), function(chr, index) { 
 
\t \t block.call(context, chr, index, string); 
 
\t }); 
 
}; 
 

 
// globally resolve forEach enumeration 
 
var forEach = function(object, block, context) { 
 
\t if (object) { 
 
\t \t var resolve = Object; // default 
 
\t \t if (object instanceof Function) { 
 
\t \t \t // functions have a "length" property 
 
\t \t \t resolve = Function; 
 
\t \t } else if (object.forEach instanceof Function) { 
 
\t \t \t // the object implements a custom forEach method so use that 
 
\t \t \t object.forEach(block, context); 
 
\t \t \t return; 
 
\t \t } else if (typeof object == "string") { 
 
\t \t \t // the object is a string 
 
\t \t \t resolve = String; 
 
\t \t } else if (typeof object.length == "number") { 
 
\t \t \t // the object is array-like 
 
\t \t \t resolve = Array; 
 
\t \t } 
 
\t \t resolve.forEach(object, block, context); 
 
\t } 
 
};
div#main { margin-left:1%; margin-right:1%; } 
 
table.sortable th:not(.sorttable_sorted):not(.sorttable_sorted_reverse):not(.sorttable_nosort):after {content: " \25B4\25BE"} 
 
table.sortable tbody tr:nth-child(2n) td {background: #ffcccc;} 
 
table.sortable tbody tr:nth-child(2n+1) td {background: #ccfffff;} 
 
.sm { font-size:small; } 
 
.text { text-align:center; }
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
 
<html> 
 
\t <head> 
 
\t \t <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
 
\t \t <title>RuneScape Quest Checklist</title> 
 
\t \t <link rel="stylesheet" href="stylesheet.css" type="text/css" charset="utf-8"> 
 
\t \t <script type="text/javascript" src="sorttable.js"></script> 
 
\t </head> 
 
<body> 
 
\t <div id="main"> 
 
\t \t <table class="sortable" border="0" cellpadding="0" cellspacing="0" width="100%"> 
 
\t \t \t <thead> 
 
\t \t \t \t <tr> 
 
\t \t \t \t \t <th class="sorttable_nosort" title="Unsortable" style="width: 55px;"><strong>Done</strong></th> 
 
\t \t \t \t \t <th title="Click to sort"><strong>Quest Name</strong></th> 
 
\t \t \t \t \t <th title="Click to sort"><strong>Difficulty</strong></th> 
 
\t \t \t \t \t <th title="Click to sort"><strong>Length</strong></th> 
 
\t \t \t \t \t <th class="sorttable_nosort" title="Unsortable"><strong>Skill Req.</strong></th> 
 
\t \t \t \t \t <th class="sorttable_nosort" title="Unsortable"><strong>Quest Req.</strong></th> 
 
\t \t \t \t \t <th title="Click to sort"><strong>QP</strong></th> 
 
\t \t \t \t \t <th class="sorttable_nosort" title="Unsortable"><strong>Rewards</strong></th> 
 
\t \t \t \t \t <th title="Click to sort"><strong>Free/Members</strong></th> 
 
\t \t \t \t </tr> 
 
\t \t \t </thead> 
 
\t \t \t <tbody> 
 
\t \t \t \t <tr> 
 
\t \t \t \t \t <td class="sm text"><input name="done[1]" value="1" type="checkbox"></td> 
 
\t \t \t \t \t <td class="sm text">Quest Name</td> 
 
\t \t \t \t \t <td class="sm text"><div style="display: none;">1</div>Novice (to Grandmaster)</td> 
 
\t \t \t \t \t <td class="sm text"><div style="display: none;">1</div>Short (to Very Long)</td> 
 
\t \t \t \t \t <td class="sm text">Various Skills</td> 
 
\t \t \t \t \t <td class="sm text">Various Quests</td> 
 
\t \t \t \t \t <td class="sm text">1 (to 3)</td> 
 
\t \t \t \t \t <td class="sm"> 
 
\t \t \t \t \t \t <ul> 
 
\t \t \t \t \t \t \t <li>Reward 1</li> 
 
\t \t \t \t \t \t \t <li>Reward 2</li> 
 
\t \t \t \t \t \t \t <li>etc...</li> 
 
\t \t \t \t \t \t </ul> 
 
\t \t \t \t \t </td> 
 
\t \t \t \t \t <td class="sm text">Membership req (or not)</td> 
 
\t \t \t \t </tr> 
 
\t \t \t </tbody> 
 
\t \t </table> 
 
\t </div> 
 
</body> 
 
</html>

+0

可能的复制的:[4709390 /表头到停留-固定在了顶-当用户-滚动-IT-外的视图-with-jque](http://stackoverflow.com/questions/4709390/table-header-to-stay-fixed-at-the-top-when-user-scrolls-it-out-of-view-with- jque)。 JQuery插件:[mottie.github.io/tablesorter/docs/example-widget-sticky-header](http://mottie.github.io/tablesorter/docs/example-widget-sticky-header.html)。使用CSS和HTML'标记'在这里解释:[www.cssbakery.com/2010/12/css-scrolling-tables-with-fixed](http://www.cssbakery.com/2010/12/css-scrolling -tables-with-fixed.html) – 2014-09-25 05:02:12

回答

1

尝试这样的例子

这个环节也对您有所帮助。 fixed header of table

html, 
 
body { 
 
    margin: 0; 
 
    padding: 0; 
 
    height: 100%; 
 
} 
 
section { 
 
    position: relative; 
 
    border: 1px solid #000; 
 
    padding-top: 37px; 
 
    background: #500; 
 
} 
 
section.positioned { 
 
    position: absolute; 
 
    top: 100px; 
 
    left: 100px; 
 
    width: 800px; 
 
    box-shadow: 0 0 15px #333; 
 
} 
 
.container { 
 
    overflow-y: auto; 
 
    height: 200px; 
 
} 
 
table { 
 
    border-spacing: 0; 
 
    width: 100%; 
 
} 
 
td + td { 
 
    border-left: 1px solid #eee; 
 
} 
 
td, 
 
th { 
 
    border-bottom: 1px solid #eee; 
 
    background: #ddd; 
 
    color: #000; 
 
    padding: 10px 25px; 
 
} 
 
th { 
 
    height: 0; 
 
    line-height: 0; 
 
    padding-top: 0; 
 
    padding-bottom: 0; 
 
    color: transparent; 
 
    border: none; 
 
    white-space: nowrap; 
 
} 
 
th div { 
 
    position: absolute; 
 
    background: transparent; 
 
    color: #fff; 
 
    padding: 9px 25px; 
 
    top: 0; 
 
    margin-left: -25px; 
 
    line-height: normal; 
 
    border-left: 1px solid #800; 
 
} 
 
th:first-child div { 
 
    border: none; 
 
}
<section class=""> 
 
    <div class="container"> 
 
    <table> 
 
     <thead> 
 
     <tr class="header"> 
 
      <th> 
 
      Table attribute name 
 
      <div>Table attribute name</div> 
 
      </th> 
 
      <th> 
 
      Value 
 
      <div>Value</div> 
 
      </th> 
 
      <th> 
 
      Description 
 
      <div>Description</div> 
 
      </th> 
 
     </tr> 
 
     </thead> 
 
     <tbody> 
 
     <tr> 
 
      <td>align</td> 
 
      <td>left, center, right</td> 
 
      <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td> 
 
     </tr> 
 
     <tr> 
 
      <td>bgcolor</td> 
 
      <td>rgb(x,x,x), #xxxxxx, colorname</td> 
 
      <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td> 
 
     </tr> 
 
     <tr> 
 
      <td>border</td> 
 
      <td>1,""</td> 
 
      <td>Specifies whether the table cells should have borders or not</td> 
 
     </tr> 
 
     <tr> 
 
      <td>cellpadding</td> 
 
      <td>pixels</td> 
 
      <td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td> 
 
     </tr> 
 
     <tr> 
 
      <td>cellspacing</td> 
 
      <td>pixels</td> 
 
      <td>Not supported in HTML5. Specifies the space between cells</td> 
 
     </tr> 
 
     <tr> 
 
      <td>frame</td> 
 
      <td>void, above, below, hsides, lhs, rhs, vsides, box, border</td> 
 
      <td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td> 
 
     </tr> 
 
     <tr> 
 
      <td>rules</td> 
 
      <td>none, groups, rows, cols, all</td> 
 
      <td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td> 
 
     </tr> 
 
     <tr> 
 
      <td>summary</td> 
 
      <td>text</td> 
 
      <td>Not supported in HTML5. Specifies a summary of the content of a table</td> 
 
     </tr> 
 
     <tr> 
 
      <td>width</td> 
 
      <td>pixels, %</td> 
 
      <td>Not supported in HTML5. Specifies the width of a table</td> 
 
     </tr> 
 
     </tbody> 
 
    </table> 
 
    </div> 
 
</section>

+0

我需要知道的是 - 如何将上面的代码合并到我的代码中(我现在已包含在我的原始文章中)?如前所述,所有的CSS都保存在样式表文件中(因为我有一些其他人帮助我编辑这些页面,我不希望他们搞乱CSS) – Porthiir 2014-09-25 14:40:59

0

我有jQuery的一个很好的/工作方案。

假设你的表的类别是 “fixed_header”,然后添加以下代码:

CSS:

.fixed_header{position:relative; border-collapse: collapse;} 

的JavaScript:

var originalHeader; 
var floatingHeader; 

$(document).ready(function() { 
    var tableObj=$('.fixed_header'); //or other CSS selector as `#tableId` 
    var tableBaseTop = tableObj.offset().top; 
    originalHeader = $('.fixed_header tr:first-child'); //change CSS selector here also 
    floatingHeader = originalHeader.clone(); 
    floatingHeader 
    .css('position', 'absolute') 
    .css('top', 0); 
    setFloatingHeaderSize(); 
    tableObj.prepend(floatingHeader); 

    $(window).scroll(function() { 
    var windowTop = $(window).scrollTop(); 
    if (windowTop > tableBaseTop && windowTop < tableBaseTop + tableObj.height() - 100) 
     floatingHeader.css('top', windowTop - tableBaseTop); 
    else floatingHeader.css('top', 0); //floating-header is just on Original-one 
    }); 
    $(window).resize(setFloatingHeaderSize); 
}); 

function setFloatingHeaderSize() { 
    var originalThs = originalHeader.find('th'); 
    var floatingThs = floatingHeader.find('th'); 
    for (var i = 0; i < originalThs.length; i++) { 
    floatingThs.eq(i) 
     .css('width', originalThs.eq(i).width()) 
     .css('height', originalThs.eq(i).height()); 
    } 
} 

最佳的一部分,你不需要更改HTML中的任何内容,它将直接在任何TABLE上工作,只需将表头中的类名(或任何其他css选择器替换为该表)修复其头部。

概念:它创建一个克隆标题(第一行)并显示在原始标题之上。我们为窗口滚动事件设置侦听器函数,当表格滚动到窗口顶部时,然后原始的一个上升,克隆一个保持在顶部,因此我们将它设置为边缘顶部滚动的高度。看到这一行:if (windowTop > tableBaseTop && windowTop < tableBaseTop + tableObj.height() - 100)

把戏您的案例:有关克隆头可点击的功能,我宁愿建议你应用事件监听器上克隆头,克隆头(以下行后):tableObj.prepend(floatingHeader);。 Coz,克隆头将总是一个顶部,当用户点击任何列头时,事件将被克隆头实际捕获。

如果您的活动会自动通过任何脚本设置(指不在你的控制),然后可尝试把(运行),该脚本后,上述(MY-JS)OR应用点击事件监听器克隆-header的原始专栏,这样如果有人点击,那么原始的点击事件也会触发。

代码例如:

function simulateClickOnOriginal() { 
    var originalThs = originalHeader.find('th'); 
    var floatingThs = floatingHeader.find('th'); 
    for (var i = 0; i < floatingThs.length; i++) { 
     floatingThs.eq(i).click(function(){ 
      originalThs.eq(i).trigger("click"); 
     }); 
    } 
}