Created
October 6, 2017 13:24
-
-
Save anonymous/1613feac7943ba575d56c7554862b430 to your computer and use it in GitHub Desktop.
JS Bin // source http://jsbin.com/pemereyuke/1
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>JS Bin</title> | |
<style id="jsbin-css"> | |
/* wrapper */ | |
.tableWrap { | |
border: solid 1px #ddd; | |
height: 100vh; | |
overflow-x: auto; | |
overflow-y: hidden; | |
position: relative; | |
background: #eee; | |
} | |
/* table */ | |
table { | |
border-collapse: collapse; | |
margin: 0; | |
padding: 0; | |
border: 0; | |
width: 100%; | |
} | |
tr { | |
height: 40px; | |
margin: 0; | |
padding: 0; | |
border-top: solid 1px #ddd; | |
} | |
tr.heading { | |
border-top: none; | |
background: #fff; | |
} | |
td, th { | |
border: none; | |
margin: 0; | |
padding: 10px; | |
min-width: 200px; | |
max-width: 200px; | |
overflow: hidden; | |
text-align: center; | |
} | |
/* grid */ | |
.vertical-overflow { | |
height: 100%; | |
position: absolute; | |
top: 40px; | |
left: 0; | |
overflow-x: hidden; | |
overflow-y: auto; | |
} | |
.grid { | |
width: 100%; | |
height: 100%; | |
margin-bottom: 40px; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="tableWrap"> | |
<table id="header"> | |
<tr class="heading"> | |
<th>Heading 1</th> | |
<th>Heading 2</th> | |
<th>Heading 3</th> | |
<th>Heading 4</th> | |
<th>Heading 5</th> | |
<th>Heading 6</th> | |
<th>Heading 7</th> | |
</tr> | |
</table> | |
<div class="vertical-overflow"> | |
<table class="grid"></table> | |
</div> | |
</div> | |
<script id="jsbin-javascript"> | |
// globals | |
let curY = 0 | |
let curDirection = 'DOWN' | |
let curOffset = 0 | |
let data = [] | |
let scrollHeight = 0 | |
const maxRows = 40 | |
const verticalOverflow = document.querySelector('.vertical-overflow') | |
const tableWrap = document.querySelector('.tableWrap') | |
// example data | |
const createRows = data => | |
data.reduce((acc, d) => { | |
acc += `<tr> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
</tr>` | |
return acc | |
}, '') | |
const createData = (offsetRows = []) => { | |
let counter = 0 | |
let dataVal = curOffset | |
data = [] | |
while (counter < maxRows) { | |
dataVal += 1 | |
data.push(dataVal) | |
counter++ | |
} | |
counter = 0 | |
const rowData = curDirection === 'DOWN' ? | |
offsetRows.concat(data) : | |
data.concat(offsetRows) | |
document.querySelector('.grid').innerHTML = createRows(rowData) | |
} | |
createData() | |
// calculations | |
const viewHeight = parseInt( | |
getComputedStyle(tableWrap).height, | |
10 | |
) | |
const tdHeight = parseInt( | |
document.querySelector('.grid td').getBoundingClientRect().top, | |
10 | |
) | |
// get offset rows | |
const getNumOffsetRows = () => Math.floor(viewHeight / tdHeight) | |
// data loader | |
const loadData = () => { | |
const numOffsetRows = curOffset > 0 ? getNumOffsetRows() : 0 | |
let offsetRows = curDirection === 'DOWN' ? | |
data.slice(data.length - numOffsetRows - 1, data.length) : | |
data.slice(0, numOffsetRows) | |
createData(offsetRows) | |
scrollGrid() | |
} | |
const scrollGrid = () => { | |
const y = curDirection === 'DOWN' ? tdHeight : scrollHeight - tdHeight | |
verticalOverflow.scrollTop = y | |
} | |
// check threshold | |
const checkThreshold = (scrollHeight) => { | |
if (curY === scrollHeight && curDirection === 'DOWN') { | |
curOffset += maxRows | |
// load data | |
loadData() | |
} else if (curY === 0 && curDirection === 'UP') { | |
curOffset -= maxRows | |
if (curOffset < 0) { | |
curOffset = 0 | |
return | |
} | |
// load data | |
loadData() | |
} | |
} | |
// vertical scroll listener | |
verticalOverflow.addEventListener('scroll', (e) => { | |
const scrollTop = parseInt(e.target.scrollTop, 10) | |
scrollHeight = parseInt(e.target.scrollHeight, 10) - viewHeight | |
// set direction | |
curDirection = scrollTop > curY ? 'DOWN' : 'UP' | |
// set current y coordinate | |
curY = scrollTop | |
// check scroll thresholds | |
checkThreshold(scrollHeight) | |
}) | |
</script> | |
<script id="jsbin-source-css" type="text/css">/* wrapper */ | |
.tableWrap { | |
border: solid 1px #ddd; | |
height: 100vh; | |
overflow-x: auto; | |
overflow-y: hidden; | |
position: relative; | |
background: #eee; | |
} | |
/* table */ | |
table { | |
border-collapse: collapse; | |
margin: 0; | |
padding: 0; | |
border: 0; | |
width: 100%; | |
} | |
tr { | |
height: 40px; | |
margin: 0; | |
padding: 0; | |
border-top: solid 1px #ddd; | |
} | |
tr.heading { | |
border-top: none; | |
background: #fff; | |
} | |
td, th { | |
border: none; | |
margin: 0; | |
padding: 10px; | |
min-width: 200px; | |
max-width: 200px; | |
overflow: hidden; | |
text-align: center; | |
} | |
/* grid */ | |
.vertical-overflow { | |
height: 100%; | |
position: absolute; | |
top: 40px; | |
left: 0; | |
overflow-x: hidden; | |
overflow-y: auto; | |
} | |
.grid { | |
width: 100%; | |
height: 100%; | |
margin-bottom: 40px; | |
} | |
</script> | |
<script id="jsbin-source-javascript" type="text/javascript">// globals | |
let curY = 0 | |
let curDirection = 'DOWN' | |
let curOffset = 0 | |
let data = [] | |
let scrollHeight = 0 | |
const maxRows = 40 | |
const verticalOverflow = document.querySelector('.vertical-overflow') | |
const tableWrap = document.querySelector('.tableWrap') | |
// example data | |
const createRows = data => | |
data.reduce((acc, d) => { | |
acc += `<tr> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
</tr>` | |
return acc | |
}, '') | |
const createData = (offsetRows = []) => { | |
let counter = 0 | |
let dataVal = curOffset | |
data = [] | |
while (counter < maxRows) { | |
dataVal += 1 | |
data.push(dataVal) | |
counter++ | |
} | |
counter = 0 | |
const rowData = curDirection === 'DOWN' ? | |
offsetRows.concat(data) : | |
data.concat(offsetRows) | |
document.querySelector('.grid').innerHTML = createRows(rowData) | |
} | |
createData() | |
// calculations | |
const viewHeight = parseInt( | |
getComputedStyle(tableWrap).height, | |
10 | |
) | |
const tdHeight = parseInt( | |
document.querySelector('.grid td').getBoundingClientRect().top, | |
10 | |
) | |
// get offset rows | |
const getNumOffsetRows = () => Math.floor(viewHeight / tdHeight) | |
// data loader | |
const loadData = () => { | |
const numOffsetRows = curOffset > 0 ? getNumOffsetRows() : 0 | |
let offsetRows = curDirection === 'DOWN' ? | |
data.slice(data.length - numOffsetRows - 1, data.length) : | |
data.slice(0, numOffsetRows) | |
createData(offsetRows) | |
scrollGrid() | |
} | |
const scrollGrid = () => { | |
const y = curDirection === 'DOWN' ? tdHeight : scrollHeight - tdHeight | |
verticalOverflow.scrollTop = y | |
} | |
// check threshold | |
const checkThreshold = (scrollHeight) => { | |
if (curY === scrollHeight && curDirection === 'DOWN') { | |
curOffset += maxRows | |
// load data | |
loadData() | |
} else if (curY === 0 && curDirection === 'UP') { | |
curOffset -= maxRows | |
if (curOffset < 0) { | |
curOffset = 0 | |
return | |
} | |
// load data | |
loadData() | |
} | |
} | |
// vertical scroll listener | |
verticalOverflow.addEventListener('scroll', (e) => { | |
const scrollTop = parseInt(e.target.scrollTop, 10) | |
scrollHeight = parseInt(e.target.scrollHeight, 10) - viewHeight | |
// set direction | |
curDirection = scrollTop > curY ? 'DOWN' : 'UP' | |
// set current y coordinate | |
curY = scrollTop | |
// check scroll thresholds | |
checkThreshold(scrollHeight) | |
}) | |
</script></body> | |
</html> |
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
/* wrapper */ | |
.tableWrap { | |
border: solid 1px #ddd; | |
height: 100vh; | |
overflow-x: auto; | |
overflow-y: hidden; | |
position: relative; | |
background: #eee; | |
} | |
/* table */ | |
table { | |
border-collapse: collapse; | |
margin: 0; | |
padding: 0; | |
border: 0; | |
width: 100%; | |
} | |
tr { | |
height: 40px; | |
margin: 0; | |
padding: 0; | |
border-top: solid 1px #ddd; | |
} | |
tr.heading { | |
border-top: none; | |
background: #fff; | |
} | |
td, th { | |
border: none; | |
margin: 0; | |
padding: 10px; | |
min-width: 200px; | |
max-width: 200px; | |
overflow: hidden; | |
text-align: center; | |
} | |
/* grid */ | |
.vertical-overflow { | |
height: 100%; | |
position: absolute; | |
top: 40px; | |
left: 0; | |
overflow-x: hidden; | |
overflow-y: auto; | |
} | |
.grid { | |
width: 100%; | |
height: 100%; | |
margin-bottom: 40px; | |
} |
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
// globals | |
let curY = 0 | |
let curDirection = 'DOWN' | |
let curOffset = 0 | |
let data = [] | |
let scrollHeight = 0 | |
const maxRows = 40 | |
const verticalOverflow = document.querySelector('.vertical-overflow') | |
const tableWrap = document.querySelector('.tableWrap') | |
// example data | |
const createRows = data => | |
data.reduce((acc, d) => { | |
acc += `<tr> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
<td>${d}</td> | |
</tr>` | |
return acc | |
}, '') | |
const createData = (offsetRows = []) => { | |
let counter = 0 | |
let dataVal = curOffset | |
data = [] | |
while (counter < maxRows) { | |
dataVal += 1 | |
data.push(dataVal) | |
counter++ | |
} | |
counter = 0 | |
const rowData = curDirection === 'DOWN' ? | |
offsetRows.concat(data) : | |
data.concat(offsetRows) | |
document.querySelector('.grid').innerHTML = createRows(rowData) | |
} | |
createData() | |
// calculations | |
const viewHeight = parseInt( | |
getComputedStyle(tableWrap).height, | |
10 | |
) | |
const tdHeight = parseInt( | |
document.querySelector('.grid td').getBoundingClientRect().top, | |
10 | |
) | |
// get offset rows | |
const getNumOffsetRows = () => Math.floor(viewHeight / tdHeight) | |
// data loader | |
const loadData = () => { | |
const numOffsetRows = curOffset > 0 ? getNumOffsetRows() : 0 | |
let offsetRows = curDirection === 'DOWN' ? | |
data.slice(data.length - numOffsetRows - 1, data.length) : | |
data.slice(0, numOffsetRows) | |
createData(offsetRows) | |
scrollGrid() | |
} | |
const scrollGrid = () => { | |
const y = curDirection === 'DOWN' ? tdHeight : scrollHeight - tdHeight | |
verticalOverflow.scrollTop = y | |
} | |
// check threshold | |
const checkThreshold = (scrollHeight) => { | |
if (curY === scrollHeight && curDirection === 'DOWN') { | |
curOffset += maxRows | |
// load data | |
loadData() | |
} else if (curY === 0 && curDirection === 'UP') { | |
curOffset -= maxRows | |
if (curOffset < 0) { | |
curOffset = 0 | |
return | |
} | |
// load data | |
loadData() | |
} | |
} | |
// vertical scroll listener | |
verticalOverflow.addEventListener('scroll', (e) => { | |
const scrollTop = parseInt(e.target.scrollTop, 10) | |
scrollHeight = parseInt(e.target.scrollHeight, 10) - viewHeight | |
// set direction | |
curDirection = scrollTop > curY ? 'DOWN' : 'UP' | |
// set current y coordinate | |
curY = scrollTop | |
// check scroll thresholds | |
checkThreshold(scrollHeight) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment