diff --git a/.gitignore b/.gitignore
index 485dee6..9968529 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
.idea
+compiled-docs/
\ No newline at end of file
diff --git a/README.md b/README.md
index 6b79626..a041aab 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-jquery.floatThead v1.1.1
+jquery.floatThead v1.2.0
=================
Float the table header without losing your events or styles.
@@ -47,3 +47,22 @@ FloatThead will not work properly in IE9 unless you have the following meta tag
With very big tables, you may also run into this exciting bug: http://stackoverflow.com/questions/5805956/internet-explorer-9-not-rendering-table-cells-properly
Watch for it.
+Change Log
+----------
+
+### 1.2.0
+
+- caption
tag support
+- faster initialization when working with large tables (and small ones)
+
+### 1.1.1
+
+- Fixed bugs introduced in 1.0.0 which caused issues in IE9
+
+### 1.0.0
+
+- Updated code to be jquery 1.9+ compliant
+
+License
+-------
+[CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)
\ No newline at end of file
diff --git a/jquery.floatThead.js b/jquery.floatThead.js
index c2f62b9..9a66960 100644
--- a/jquery.floatThead.js
+++ b/jquery.floatThead.js
@@ -1,9 +1,11 @@
/*!
* jQuery.floatThead
- * Copyright (c) 2012 - 2013 Misha Koryak - https://github.com/mkoryak/floatThead
+ * Copyright (c) 2012 - 2013 Misha Koryak
* Licensed under Attribution-ShareAlike 4.0 International - http://creativecommons.org/licenses/by-sa/4.0/
- * Date: 10/2/13
+ * Date: 12/12/13
*
+ * @author Misha Koryak
+ * @version 1.2.0
* @projectDescription lock a table header in place while scrolling - without breaking styles or events bound to the header
*
* Dependencies:
@@ -12,36 +14,19 @@
*
* http://mkoryak.github.io/floatThead/
*
- * Tested on FF13+, Chrome 21+, IE9, IE8
+ * Tested on FF13+, Chrome 21+, IE8, IE9, IE10
*
- * @author Misha Koryak
- * @version 1.1.1
*/
// ==ClosureCompiler==
// @compilation_level SIMPLE_OPTIMIZATIONS
// @output_file_name jquery.floatThead.min.js
// ==/ClosureCompiler==
/**
- * @preserve jQuery.floatThead 1.1.1
+ * @preserve jQuery.floatThead 1.2.0
* Copyright (c) 2013 Misha Koryak - http://mkoryak.github.io/floatThead/
* Licensed under http://creativecommons.org/licenses/by-sa/4.0/
*/
(function( $ ) {
-
-//browser stuff
- var ieVersion = function(){for(var a=3,b=document.createElement("b"),c=b.all||[];b.innerHTML="",c[0];);return 4 |
");
- $('body').append($table);
- var width = $table.find('col').width();
- $table.remove();
- return width == 0;
- };
-
/**
* provides a default config object. You can modify this after including this script if you want to change the init defaults
* @type {Object}
@@ -51,9 +36,8 @@
cellTag: 'th',
zIndex: 1001, //zindex of the floating thead (actually a container div)
debounceResizeMs: 1,
- useAbsolutePositioning: true, //if set to NULL - defaults: has scrollContainer=true, doesnt have scrollContainer=false
+ useAbsolutePositioning: true, //if set to NULL - defaults: has scrollContainer=true, doesn't have scrollContainer=false
scrollingTop: 0, //String or function($table) - offset from top of window where the header should not pass above
- //TODO: this got lost somewhere - needs to be re-implemented
scrollingBottom: 0, //String or function($table) - offset from the bottom of the table where the header should stop scrolling
scrollContainer: function($table){
return $([]); //if the table has horizontal scroll bars then this is the container that has overflow:auto and causes those scroll bars
@@ -63,10 +47,26 @@
// it should return a jquery object containing a wrapped set of table cells comprising a row that contains no col spans and is visible
return $table.find('tbody tr:visible:first>td');
},
- floatTableClass: 'floatThead-table'
+ floatTableClass: 'floatThead-table',
+ debug: false //print possible issues (that don't prevent script loading) to console, if console exists.
}
};
+
+ //browser stuff
+ var ieVersion = function(){for(var a=3,b=document.createElement("b"),c=b.all||[];b.innerHTML="",c[0];);return 4 |
");
+ $('body').append($table);
+ var width = $table.find('col').width();
+ $table.remove();
+ return width == 0;
+ };
+
var $window = $(window);
var floatTheadCreated = 0;
@@ -89,6 +89,11 @@
$window.bind('resize.floatTHead', debouncedCb);
}
+
+ function debug(str){
+ window.console && window.console && window.console.log && window.console.log(str);
+ }
+
/**
* try to calculate the scrollbar width for your browser/os
* @return {Number}
@@ -141,7 +146,7 @@
this.filter('table').each(function(){
var obj = $(this).data('floatThead-attached');
if(obj && _.isFunction(obj[command])){
- r = obj[command]();
+ var r = obj[command]();
if(typeof r !== 'undefined'){
ret = r;
}
@@ -151,6 +156,11 @@
}
var opts = $.extend({}, $.floatThead.defaults, map);
+ _.each(map, function(val, key){
+ if((!(key in $.floatThead.defaults)) && opts.debug){
+ debug("jQuery.floatThead: used ["+key+"] key to init plugin, but that param is not an option for the plugin. Valid options are: "+ (_.keys($.floatThead.defaults)).join(', '));
+ }
+ });
this.filter(':not(.'+opts.floatTableClass+')').each(function(){
var $table = $(this);
@@ -176,12 +186,17 @@
if(useAbsolutePositioning == null){ //defaults: locked=true, !locked=false
useAbsolutePositioning = opts.scrollContainer($table).length;
}
+ var $caption = $table.find("caption");
+ var haveCaption = $caption.length == 1;
+ if(haveCaption){
+ var captionAlignTop = ($caption.css("caption-side") || $caption.attr("align") || "top") === "top";
+ }
var $fthGrp = $('');
var locked = $scrollContainer.length > 0;
var wrappedContainer = false; //used with absolute positioning enabled. did we need to wrap the scrollContainer/table with a relative div?
- var absoluteToFixedOnScroll = ieVersion && !locked && useAbsolutePositioning; //on ie using absolute positioning doesnt look good with window scrolling, so we change positon to fixed on scroll, and then change it back to absolute when done.
+ var absoluteToFixedOnScroll = ieVersion <= 9 && !locked && useAbsolutePositioning; //on ie using absolute positioning doesnt look good with window scrolling, so we change positon to fixed on scroll, and then change it back to absolute when done.
var $floatTable = $("
");
var $floatColGroup = $("");
var $tableColGroup = $("");
@@ -306,7 +321,6 @@
return count;
}
-
function refloat(){ //make the thing float
if(!headerFloated){
headerFloated = true;
@@ -352,33 +366,22 @@
var i;
var numCols = columnNum(); //if the tables columns change dynamically since last time (datatables) we need to rebuild the sizer rows and get new count
return function(){
- var badReflow = false;
-
var $rowCells = getSizingRow($table, $tableCells, $fthCells, ieVersion);
if($rowCells.length == numCols && numCols > 0){
unfloat();
for(i=0; i < numCols; i++){
- var $rowCell = $rowCells.eq(i);
- var rowWidth = $rowCell.outerWidth(true);
- $headerCells.eq(i).outerWidth(rowWidth);
- $tableCells.eq(i).outerWidth(rowWidth);
+ var _rowcell = $rowCells.get(i);
+ var rowWidth = _rowcell.offsetWidth;
+ $headerCells.eq(i).width(rowWidth);
+ $tableCells.eq(i).width(rowWidth);
}
refloat();
- for(i=0; i < numCols; i++){
- var hw = $headerCells.eq(i).outerWidth(true);
- var tw = $tableCells.eq(i).outerWidth(true);
- if(hw != tw){
- badReflow = true;
- break;
- }
- }
} else {
$floatTable.append($header);
$table.css(layoutAuto);
$floatTable.css(layoutAuto);
setHeaderHeight();
}
- return badReflow;
};
}
@@ -393,12 +396,16 @@
//this floatEnd calc was moved out of the returned function because we assume the table height doesnt change (otherwise we must reinit by calling calculateFloatContainerPosFn)
var floatEnd;
var tableContainerGap = 0;
+ var captionHeight = haveCaption ? $caption.outerHeight(true) : 0;
var floatContainerHeight = $floatContainer.height();
var tableOffset = $table.offset();
if(locked){
var containerOffset = $scrollContainer.offset();
tableContainerGap = tableOffset.top - containerOffset.top + scrollingContainerTop;
+ if(haveCaption && captionAlignTop){
+ tableContainerGap += captionHeight;
+ }
} else {
floatEnd = tableOffset.top - scrollingTop - floatContainerHeight + scrollingBottom + scrollbarOffset.horizontal;
}
@@ -437,8 +444,10 @@
}
tableOffset = $table.offset();
+ if(haveCaption && captionAlignTop){
+ tableOffset.top += captionHeight;
+ }
var top, left, tableHeight;
-// console.log("locked: "+locked+" use abs: "+useAbsolutePositioning)
if(locked && useAbsolutePositioning){ //inner scrolling, absolute positioning
if (tableContainerGap >= scrollingContainerTop) {
@@ -452,13 +461,13 @@
left = 0;
} else if(!locked && useAbsolutePositioning) { //window scrolling, absolute positioning
tableHeight = $table.outerHeight();
- if(windowTop > floatEnd + tableHeight){
- top = tableHeight - floatContainerHeight; //scrolled past table
+ if(windowTop > floatEnd + tableHeight + captionHeight){
+ top = tableHeight - floatContainerHeight + captionHeight; //scrolled past table
} else if (tableOffset.top > windowTop + scrollingTop) {
top = 0; //scrolling to table
unfloat();
} else {
- top = scrollingTop + windowTop - tableOffset.top + tableContainerGap;
+ top = scrollingTop + windowTop - tableOffset.top + tableContainerGap + captionHeight;
refloat(); //scrolling within table. header floated
}
left = 0;
@@ -474,8 +483,8 @@
left = tableOffset.left + scrollContainerLeft - windowLeft;
} else if(!locked && !useAbsolutePositioning) { //window scrolling, fixed positioning
tableHeight = $table.outerHeight();
- if(windowTop > floatEnd + tableHeight){
- top = tableHeight + scrollingTop - windowTop + floatEnd;
+ if(windowTop > floatEnd + tableHeight + captionHeight){
+ top = tableHeight + scrollingTop - windowTop + floatEnd + captionHeight;
//scrolled past the bottom of the table
} else if (tableOffset.top > windowTop + scrollingTop) {
top = tableOffset.top - windowTop;
@@ -554,10 +563,7 @@
var ensureReflow = function(){
flow = reflow();
- var badReflow = flow();
- if(badReflow){
- flow();
- }
+ flow();
};
var windowResizeEvent = function(){
diff --git a/jquery.floatThead.min.js b/jquery.floatThead.min.js
index abded97..8b91a3b 100644
--- a/jquery.floatThead.min.js
+++ b/jquery.floatThead.min.js
@@ -1,19 +1,19 @@
/*
- jQuery.floatThead 1.1.1
+ jQuery.floatThead 1.2.0
Copyright (c) 2013 Misha Koryak - http://mkoryak.github.io/floatThead/
Licensed under http://creativecommons.org/licenses/by-sa/4.0/
*/
-(function(a){function ea(a,c){var d=l.width(),fa=_.debounce(function(){var a=l.width();d!=a&&(d=a,c())},a);l.bind("resize.floatTHead",fa)}function ga(){var e=a('');a("body").append(e);var c=e.innerWidth(),d=a("div",e).innerWidth();e.remove();return c-d}function ha(a){if(a.dataTableSettings)for(var c=0;c
|
");a("body").append(e);var c=e.find("col").width();e.remove();return 0==c};a.floatThead={defaults:{cellTag:"th",zIndex:1001,debounceResizeMs:1,useAbsolutePositioning:!0,scrollingTop:0,scrollingBottom:0,
- scrollContainer:function(e){return a([])},getSizingRow:function(a,c,d){return a.find("tbody tr:visible:first>td")},floatTableClass:"floatThead-table"}};var l=a(window),J=0;a.fn.floatThead=function(e){if(8>D)return this;null==v&&(v=I())&&(document.createElement("fthtr"),document.createElement("fthtd"),document.createElement("fthfoot"));if(_.isString(e)){var c=this;this.filter("table").each(function(){var d=a(this).data("floatThead-attached");d&&_.isFunction(d[e])&&(r=d[e](),"undefined"!==typeof r&&
- (c=r))});return c}var d=a.extend({},a.floatThead.defaults,e);this.filter(":not(."+d.floatTableClass+")").each(function(){function c(){var g=t.outerHeight(!0);K.outerHeight(g);ia.outerHeight(g)}function e(){w=(_.isFunction(d.scrollingTop)?d.scrollingTop(b):d.scrollingTop)||0;W=(_.isFunction(d.scrollingBottom)?d.scrollingBottom(b):d.scrollingBottom)||0}function I(){var g=t.find("tr:first>"+d.cellTag),g=_.reduce(g,function(g,b){var d=parseInt(a(b).attr("colspan")||1,10);return g+d},0);if(g!=X){X=g;for(var b=
- [],p=[],f=[],h=0;h'),p.push(""),f.push("");p=p.join("");b=b.join("");v&&(f=f.join(""),L.html(f),M=L.find("fthtd"));K.html(b);E.html(p);F=E.find("col");N.html(p);O=N.find("col")}return g}function G(){H||(H=!0,b.css(Y),n.css(Y),n.append(t),ja.before(A),c())}function P(){H&&(H=!1,A.detach(),b.prepend(t),b.css(B),n.css(B))}function Z(g){q!=g&&(q=g,k.css({position:q?"absolute":"fixed"}))}
- function Q(){var g,a=I();return function(){var p=!1,f;f=F;f=v?M:D?d.getSizingRow(b,f,M):f;if(f.length==a&&0e||0>n)){if(ka)"windowScrollDone"==c?Z(!0):Z(!1);else if("windowScrollDone"==c)return null;h=b.offset();var k,s;u&&q?(p>=a?(c=p-a,k=0d+c?k=c-f:h.top>e+w?(k=0,P()):(k=w+e-h.top+p,G()),s=0):
- u&&!q?(p>a?(k=h.top-e,P()):(k=h.top+a-e-p,G()),s=h.left+t-n):u||q||(c=b.outerHeight(),e>d+c?k=c+w-e+d:h.top>e+w?(k=h.top-e,G()):k=w,s=h.left-n);return{top:k,left:s}}}}function aa(){var a=null,d=null,e=null;return function(f,h,l){null==f||a==f.top&&d==f.left||(k.css({top:f.top,left:f.left}),a=f.top,d=f.left);h&&(f=b.outerWidth(),h=m.width()||f,k.width(h-C.vertical),u?n.css("width",100*f/(h-C.vertical)+"%"):n.outerWidth(f));l&&c();l=m.scrollLeft();e!=l&&(k.scrollLeft(l),e=l)}}function S(){m.length&&
- (C.horizontal=m.width() element");var H=!0,w,W,C={vertical:0,horizontal:0},ba=ga(),X=0,m=d.scrollContainer(b)||a([]),q=d.useAbsolutePositioning;
- null==q&&(q=d.scrollContainer(b).length);var T=a(''),u=0"),N=a(""),E=a(""),L=a(''),k=a(''),A=a(""),K=a('
'),ia=a([]),F=a([]),O=a([]),M=a([]);A.append(K);t.detach();b.prepend(A);b.prepend(E);v&&(T.append(L),b.append(T));n.append(N);k.append(n);n.attr("class",b.attr("class"));n.addClass(d.floatTableClass).css("margin",
- 0);if(q){var ca=function(a,b){var c=a.css("position");if("relative"!=c&&"absolute"!=c||b)c={paddingLeft:a.css("paddingLeft"),paddingRight:a.css("paddingRight")},k.css(c),a=a.wrap("").parent(),$=!0;return a};u?ca(m,!0).append(k):(ca(b),b.after(k))}else b.after(k);k.css({position:q?"absolute":"fixed",marginTop:0,top:q?0:"auto",zIndex:d.zIndex});e();var Y={"table-layout":"fixed"},B={"table-layout":b.css("tableLayout")||"auto"};S();var x=Q();x();var s=
- R(),y=aa();y(s("init"),!0);var la=_.debounce(function(){y(s("windowScrollDone"),!1)},300),U=function(){y(s("windowScroll"),!1);la()},V=function(){y(s("containerScroll"),!1)},da=function(){e();S();x=Q();x()&&x();s=R();y=aa();y(s("resize"),!0,!0)},z=_.debounce(function(){S();e();x=Q();x()&&x();s=R();y(s("reflow"),!0)},1);u?q?m.bind("scroll.floatTHead",V):(m.bind("scroll.floatTHead",V),l.bind("scroll.floatTHead",U)):l.bind("scroll.floatTHead",U);l.bind("load.floatTHead",z);ea(d.debounceResizeMs,da);
- b.bind("reflow",z);ha(b)&&b.bind("filter",z).bind("sort",z).bind("page",z);b.data("floatThead-attached",{destroy:function(){b.css(B);E.remove();v&&T.remove();A.parent().length&&A.replaceWith(t);b.unbind("reflow");z=da=V=U=function(){};m.unbind("scroll.floatTHead");k.remove();b.data("floatThead-attached",!1);J--;0==J&&(l.unbind("scroll.floatTHead"),l.unbind("resize.floatTHead"),l.unbind("load.floatTHead"))},reflow:function(){z()},setHeaderHeight:function(){c()},getFloatContainer:function(){return k}});
- J++});return this}})(jQuery);
+(function(a){function ha(a,d){var b=e.width(),ia=_.debounce(function(){var a=e.width();b!=a&&(b=a,d())},a);e.bind("resize.floatTHead",ia)}function ja(){var g=a('');a("body").append(g);var d=g.innerWidth(),b=a("div",g).innerWidth();g.remove();return d-b}function ka(a){if(a.dataTableSettings)for(var d=0;d
td")},floatTableClass:"floatThead-table",debug:!1}};var D=function(){for(var a=3,d=document.createElement("b"),b=d.all||[];d.innerHTML="\x3c!--[if gt IE "+ ++a+"]> |
");a("body").append(e);var d=e.find("col").width();e.remove();return 0==d},e=a(window),K=0;a.fn.floatThead=function(g){if(8>D)return this;null==v&&(v=J())&&(document.createElement("fthtr"),document.createElement("fthtd"),document.createElement("fthfoot"));if(_.isString(g)){var d=this;this.filter("table").each(function(){var b=a(this).data("floatThead-attached");b&&_.isFunction(b[g])&&(b=b[g](),"undefined"!==
+ typeof b&&(d=b))});return d}var b=a.extend({},a.floatThead.defaults,g);_.each(g,function(e,d){if(!(d in a.floatThead.defaults)&&b.debug){var g="jQuery.floatThead: used ["+d+"] key to init plugin, but that param is not an option for the plugin. Valid options are: "+_.keys(a.floatThead.defaults).join(", ");window.console&&window.console&&window.console.log&&window.console.log(g)}});this.filter(":not(."+b.floatTableClass+")").each(function(){function d(){var a=n.outerHeight(!0);L.outerHeight(a);la.outerHeight(a)}
+ function g(){w=(_.isFunction(b.scrollingTop)?b.scrollingTop(c):b.scrollingTop)||0;X=(_.isFunction(b.scrollingBottom)?b.scrollingBottom(c):b.scrollingBottom)||0}function J(){var c=n.find("tr:first>"+b.cellTag),c=_.reduce(c,function(c,b){var d=parseInt(a(b).attr("colspan")||1,10);return c+d},0);if(c!=Y){Y=c;for(var d=[],s=[],f=[],e=0;e'),s.push(""),f.push("");s=s.join("");d=d.join("");
+ v&&(f=f.join(""),M.html(f),N=M.find("fthtd"));L.html(d);E.html(s);O=E.find("col");P.html(s);Z=P.find("col")}return c}function F(){G||(G=!0,c.css($),h.css($),h.append(n),ma.before(z),d())}function Q(){G&&(G=!1,z.detach(),c.prepend(n),c.css(A),h.css(A))}function aa(a){p!=a&&(p=a,l.css({position:p?"absolute":"fixed"}))}function R(){var a,e=J();return function(){var s;s=O;s=v?N:D?b.getSizingRow(c,s,N):s;if(s.length==e&&0r||0>n)){if(na)"windowScrollDone"==
+ q?aa(!0):aa(!1);else if("windowScrollDone"==q)return null;k=c.offset();H&&ba&&(k.top+=f);var h,l;u&&p?(d>=a?(q=d-a,h=0b+q+f?h=q-g+f:k.top>r+w?(h=0,Q()):(h=w+r-k.top+d+f,F()),l=0):u&&!p?(d>a?(h=k.top-r,Q()):(h=k.top+a-r-d,F()),l=k.left+t-n):u||p||(q=c.outerHeight(),r>b+q+f?h=q+w-r+b+f:k.top>r+w?(h=k.top-r,F()):h=w,l=k.left-n);return{top:h,left:l}}}}function da(){var a=null,b=null,e=null;return function(f,g,k){null==f||a==f.top&&b==f.left||(l.css({top:f.top,
+ left:f.left}),a=f.top,b=f.left);g&&(f=c.outerWidth(),g=m.width()||f,l.width(g-B.vertical),u?h.css("width",100*f/(g-B.vertical)+"%"):h.outerWidth(f));k&&d();k=m.scrollLeft();e!=k&&(l.scrollLeft(k),e=k)}}function T(){m.length&&(B.horizontal=m.width() element");var G=!0,w,X,B={vertical:0,horizontal:0},ea=ja(),Y=0,m=b.scrollContainer(c)||a([]),p=b.useAbsolutePositioning;null==p&&(p=b.scrollContainer(c).length);var I=c.find("caption"),H=1==I.length;if(H)var ba="top"===(I.css("caption-side")||I.attr("align")||"top");var U=a(''),u=0=D&&!u&&p,h=a(""),P=a(""),
+ E=a(""),M=a(''),l=a(''),z=a(""),L=a('
'),la=a([]),O=a([]),Z=a([]),N=a([]);z.append(L);n.detach();c.prepend(z);c.prepend(E);v&&(U.append(M),c.append(U));h.append(P);l.append(h);h.attr("class",c.attr("class"));h.addClass(b.floatTableClass).css("margin",0);if(p){var fa=function(a,c){var b=a.css("position");if("relative"!=b&&"absolute"!=b||c)b={paddingLeft:a.css("paddingLeft"),paddingRight:a.css("paddingRight")},
+ l.css(b),a=a.wrap("").parent(),ca=!0;return a};u?fa(m,!0).append(l):(fa(c),c.after(l))}else c.after(l);l.css({position:p?"absolute":"fixed",marginTop:0,top:p?0:"auto",zIndex:b.zIndex});g();var $={"table-layout":"fixed"},A={"table-layout":c.css("tableLayout")||"auto"};T();var C=R();C();var t=S(),x=da();x(t("init"),!0);var oa=_.debounce(function(){x(t("windowScrollDone"),!1)},300),V=function(){x(t("windowScroll"),!1);oa()},W=function(){x(t("containerScroll"),
+ !1)},ga=function(){g();T();C=R();C();t=S();x=da();x(t("resize"),!0,!0)},y=_.debounce(function(){T();g();C=R();C();t=S();x(t("reflow"),!0)},1);u?p?m.bind("scroll.floatTHead",W):(m.bind("scroll.floatTHead",W),e.bind("scroll.floatTHead",V)):e.bind("scroll.floatTHead",V);e.bind("load.floatTHead",y);ha(b.debounceResizeMs,ga);c.bind("reflow",y);ka(c)&&c.bind("filter",y).bind("sort",y).bind("page",y);c.data("floatThead-attached",{destroy:function(){c.css(A);E.remove();v&&U.remove();z.parent().length&&z.replaceWith(n);
+ c.unbind("reflow");y=ga=W=V=function(){};m.unbind("scroll.floatTHead");l.remove();c.data("floatThead-attached",!1);K--;0==K&&(e.unbind("scroll.floatTHead"),e.unbind("resize.floatTHead"),e.unbind("load.floatTHead"))},reflow:function(){y()},setHeaderHeight:function(){d()},getFloatContainer:function(){return l}});K++});return this}})(jQuery);
\ No newline at end of file