Skip to content

Instantly share code, notes, and snippets.

@smagch
Last active September 9, 2016 16:45
Show Gist options
  • Save smagch/15d6656a408a31a32ecbb0285573a6fb to your computer and use it in GitHub Desktop.
Save smagch/15d6656a408a31a32ecbb0285573a6fb to your computer and use it in GitHub Desktop.
Scroll Selection testing
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style media="screen">
#container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
scroll-behavior: smooth;
overflow: scroll;
}
.box {
min-height: 200px;
width: 300px;
border: 10px solid white;
}
.box.selected {
border-color: blue;
}
.red {
background-color: red;
}
.blue {
background-color: yellow;
}
.green {
background-color: green;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
let colors = ['red', 'blue', 'green'];
let frag = document.createDocumentFragment();
for (var i = 0; i < 30; i++) {
let element = document.createElement('div');
if (i !== 0 && i !== 29) {
element.style.height = 200 + Math.floor(Math.random() * 400) + 'px';
}
let color = colors[i%3];
element.classList.add(color, 'box');
frag.appendChild(element);
}
let container = document.querySelector('#container');
container.appendChild(frag);
container.addEventListener('wheel', handleWeel);
let selected = container.firstChild;
selected.classList.add('selected');
let deltaY = -0.5 * container.offsetHeight;
function handleWeel(e) {
if (isOnTopCorner()) {
deltaY += e.deltaY;
if (deltaY < 0) {
e.preventDefault();
deltaY = Math.max(deltaY, -0.5 * container.offsetHeight);
} else {
deltaY = 0;
}
//console.log('deltaY: ', deltaY);
}
if (isOnBottomCorner()) {
deltaY += e.deltaY;
if (deltaY > 0) {
e.preventDefault();
deltaY = Math.min(deltaY, 0.5 * container.offsetHeight);
} else {
deltaY = 0;
}
//console.log('deltaY: ', deltaY);
}
if (e.deltaY > 0) {
checkSelectedBottom();
} else if (e.deltaY < 0) {
checkSelectedTop();
}
}
function isOnTopCorner() {
return container.scrollTop === 0;
}
function isOnBottomCorner() {
return container.scrollTop + container.offsetHeight >= container.scrollHeight;
}
function isOnCorner() {
return isOnTopCorner() || isOnBottomCorner();
}
function getMiddle() {
let middle = container.scrollTop + container.offsetHeight * 0.5;
if (isOnCorner()) {
middle += deltaY;
}
return middle;
}
function checkSelectedTop() {
let screenMiddle = getMiddle();
let current = selected;
while (screenMiddle < current.offsetTop) {
current = current.previousSibling;
if (!current) {
return;
}
}
updateSelected(current);
}
function checkSelectedBottom() {
let screenMiddle = getMiddle();
let current = selected;
while (screenMiddle > current.offsetTop + current.offsetHeight) {
current = current.nextSibling;
if (!current) {
return;
}
}
updateSelected(current);
}
function updateSelected(element) {
if (element === selected) {
return;
}
selected.classList.remove('selected');
element.classList.add('selected');
selected = element;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment