Last active
November 3, 2017 18:28
-
-
Save Cyken-Zeraux/62cd2f6420ffc56e61bf79800583e544 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function fixedtableheader (){ | |
var tickingImages = false; | |
var allTables = document.getElementsByTagName('table'); | |
Array.prototype.filter.call(allTables,function(table){ | |
//Just get an array of all the tr's in the table | |
if(!$(table).hasClass( "stickyheader" ) return; | |
var trs = table.getElementsByTagName('tr'); | |
//If there's more than one tr, then we proceed and treat the first one as the header | |
//Probably needs some change | |
if(trs.length < 2) return; | |
var firstTr = trs[0]; | |
if(!firstTr) return; | |
//we clone our TR, making a face deepclone | |
var tickingPositions = null; | |
var tickingHeaders = null; | |
var tableOffsetTop = 0; | |
var tableHeight =100; | |
var headerHidden = true; | |
var oldScroll = 0; | |
var oldTableWidth = 0; | |
var oldFirstTrWidth = 0; | |
var oldTableOffset = null; | |
var trClone = firstTr.cloneNode(true); | |
table.style.overflowY='hidden' | |
//we set the proper styling basics. | |
trClone.style.visibility='hidden' | |
trClone.style.top='0' | |
trClone.style.position= 'fixed' | |
trClone.style.overflowX= 'hidden' | |
if(navigator.userAgent.match(/firefox/i)){ | |
trClone.style.marginLeft = '-2px' | |
} | |
// we append the fake header child to the thead. | |
firstTr.insertAdjacentElement('afterend',trClone); | |
for(var i = 0 ; i < trClone.children.length ; i++){ | |
trClone.children[i].addEventListener('click', function(e){ | |
e.preventDefault(); //stop it from doing anything stupid | |
e.stopPropagation(); //stop it from bubbling | |
var j = 1; | |
var child = e.target; | |
while(child = child.previousSibling != null) j++ | |
firstTr.children[j].click(); //trigger click event on real child element instead. | |
}) | |
var spacer = document.createElement('div'); | |
spacer.style.width = '10px'; | |
spacer.style.height= '1px'; | |
trClone.children[i].appendChild(spacer); | |
} | |
//recaling when page resizes. | |
table.addEventListener('resize', throttleRecalcPositions,false); | |
window.addEventListener('resize', throttleRecalcPositions,false); | |
table.addEventListener('resize', throttleRecalcHeaders,false); | |
window.addEventListener('resize', throttleRecalcHeaders,false); | |
//creating events for when the page gets scrolled. | |
document.addEventListener('scroll', throttleRecalcPositions,false); //this is an insurance policy. | |
//onhashtagh change for the tabs | |
window.addEventListener('hashchange', function(){ | |
setTimeout(function(){ | |
recalcTableSizes(); | |
recalcHeaderSizes(); | |
recalcPositions(); | |
},33) | |
}) | |
//hooking up fake scrollbar | |
trClone.addEventListener('scroll', function(e){ | |
if(e.target!=trClone) return; | |
table.scrollLeft = trClone.scrollLeft ; | |
}) | |
table.addEventListener('scroll', function(e){ | |
if(e.target!=table) return; | |
trClone.scrollLeft = table.scrollLeft ; | |
}) | |
function throttleRecalcHeaders(){ | |
if (!tickingHeaders){ | |
tickingHeaders = setTimeout(function(){ | |
recalcTableSizes(); | |
recalcHeaderSizes(); | |
tickingHeaders = null; | |
},33); | |
} | |
} | |
function throttleRecalcPositions(){ | |
if (!tickingPositions){ | |
tickingPositions = window.requestAnimationFrame(function(){ | |
recalcPositions(); | |
if(window.pageYOffset > oldScroll + 100 || window.pageYOffset < oldScroll - 100){ | |
recalcTableSizes(); | |
oldScroll = window.pageYOffset | |
} | |
tickingPositions = null; | |
}); | |
} | |
} | |
recalcTableSizes(); | |
recalcHeaderSizes(); | |
recalcPositions(); | |
function recalcTableSizes(){ | |
var rect = table.getBoundingClientRect(); | |
tableOffsetTop = rect.top + window.pageYOffset; | |
tableHeight = rect.height | |
} | |
function recalcHeaderSizes(){ | |
var tableRect = table.getBoundingClientRect(); | |
var firstTrRect = firstTr.getBoundingClientRect(); | |
var trCloneRect = trClone.getBoundingClientRect(); | |
if(tableRect.width == oldTableWidth && firstTrRect.width == oldFirstTrWidth) return ; //nothing changed in the headers. | |
//acquire the exact width of the property without padding, margin, borders | |
try {trClone.style.width = window.getComputedStyle( table, null).getPropertyValue('width');} | |
catch(e) {trClone.style.width = table.currentStyle.width;} | |
for(var i = 0 ; i < trClone.children.length ;i++){ | |
try {trClone.children[i].children[0].style.width = window.getComputedStyle( firstTr.children[i], null).getPropertyValue('width')} | |
catch(e) {trClone.children[i].children[0].style.width = firstTr.children[i].currentStyle.width;} | |
if(navigator.userAgent.match(/firefox/i)){ | |
trClone.children[i].children[0].style.width =trClone.children[i].children[0].style.width -4; | |
} | |
} | |
oldTableWidth = tableRect.width; | |
oldFirstTrWidth = firstTrRect.width; | |
} | |
function recalcPositions(){ | |
//first check if the table is still in range | |
if(window.pageYOffset > tableOffsetTop && window.pageYOffset < tableOffsetTop + tableHeight){ | |
if(headerHidden == true) { | |
trClone.style.visibility = 'visible' | |
headerHidden = false; | |
} | |
} | |
else if( headerHidden == false ){ | |
trClone.style.visibility = 'hidden' | |
headerHidden = true; | |
} | |
} | |
}) | |
} | |
$(document).ready(fixedtableheader); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment