<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Скроллинг клавишами и липкие блоки</title>
</head>
<style>
.menu {
position: fixed;
left: 0%;
top: 0%;
background: maroon;
width: 100%;
height: 10%;
z-index: 10;
}
#content {
position: absolute;
left: 0%;
top: 10%;
}
.table {
position: relative;
background: gray;
}
.block {
position: relative;
width: 500px;
background: lightgray;
border: 1px solid black;
}
.stickerBlock {
background: gray;
border: 1px solid black;
width: 200px;
vertical-align: top;
}
.sticker {
position: relative;
background: whitesmoke;
height: 100px;
width: 200px;
}
</style>
<div class="menu"></div>
<div id="content"></div>
<script>
window.onload = function () {//onload begin
var content = document.getElementById('content');
var inner = '';
var str = '';
for (var i = 0; i < 3; i++) {
str += '<table class="table">'
for (var j = 0; j < 3; j++) {
str += '<tr><td class="block">';
for (var k = 0; k < 31; k++) {
inner += 'таблица ' + i + '; строка ' + j + '<br>';
}
str += inner + '</td><td class="stickerBlock"><div class="sticker">sticker ' + i + ' - ' + j + '</div></td></tr>';
inner = '';
}
str += '</table>';
}
content.innerHTML = str;
var getCoords = function (element) {//getCoords begin
var rect = element.getBoundingClientRect();
var docEl = document.documentElement;
var body = document.body;
var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
var clientLeft = docEl.clientLeft || body.clientLeft || 0;
var clientTop = docEl.clientTop || body.clientTop || 0;
var left = rect.left + scrollLeft - clientLeft;
var top = rect.top + scrollTop - clientTop;
var right = rect.right + scrollLeft - clientLeft;
var bottom = rect.bottom + scrollTop - clientTop;
return {left: left, top: top, bottom: bottom, right: right}
}//getCoords end
if (!content.getElementsByClassName) { //if begin
content.getElementsByClassName = function(cl) {//getElementsByClassName begin
var retnode = [];
var myclass = new RegExp('\\b'+cl+'\\b');
var elem = this.getElementsByTagName('*');
for (var i = 0; i < elem.length; i++) {
var classes = elem[i].className;
if (myclass.test(classes)) {
retnode.push(elem[i]);
}
}
return retnode;
}//getElementsByClassName end
}//if end
/*
if (!content.getElementsByClassName) { //if begin
content.getElementsByClassName = function(nameOfClass) {//getElementsByClassName begin
var mas = [];
var elements = this.getElementsByTagName('*');
var length = elements.length;
for (var i = 0; i < length; i++) {
if (elements[i].className == nameOfClass) {
mas.push(elements[i]);
}
}
return mas;
}//getElementsByClassName end
}//if end
*/
//скроллинг клавишами++++++++++++++++++++++++++++++++++++++++++++++++++++++
document.onkeyup = function (e) {//onkeyup begin
var e = e || window.event; //для IE
var getNUp = function(collection, boundary) {//getNUp begin
var scroll = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var sum = scroll + boundary;
var length = collection.length;
var coords = {};
for (var i = 0; i < length; i++) {//for begin
coords = getCoords(collection[i]);
if (coords.top >= sum && i != 0) {
return (i - 1);
} else if (coords.bottom > sum) {
return i;
}
}//for end
return (i - 1);
}//getNUp end
var getNDown = function (collection, boundary) {//getNDown begin
var scroll = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var sum = scroll + boundary;
var length = collection.length;
var coords = {};
for (var i = 0; i < length; i++) {//for begin
coords = getCoords(collection[i]);
if (i == 0 && coords.top > sum + 1) {return i}
if (coords.bottom > sum && i != length - 1) {
return (i + 1);
} else if (coords.top > sum) {
return i;
}
}//for end
return (i - 1);
}//getNDown end
var blocks = content.getElementsByClassName('block');
var upperBound = getCoords(blocks[0]).top;
var leftBound = getCoords(blocks[0]).left;
var n = 0;
switch ( e.keyCode ) {//switch begin
case 65: {
var n = getNUp(blocks, upperBound);
break;
}
case 83: {
var n = getNDown(blocks, upperBound);
break;
}
default: return;
}//switch begin
window.scrollTo(getCoords(blocks[n]).left - leftBound, getCoords(blocks[n]).top - upperBound);
}//onkeyup end
//липкие блоки+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
window.onscroll = function () {//onscroll begin
var stickerBlocks = content.getElementsByClassName('stickerBlock');
var stickers = content.getElementsByClassName('sticker');
var length = stickers.length;
var upperBound = getCoords(stickerBlocks[0]).top;
var leftBound = getCoords(stickerBlocks[0]).left;
var scroll = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var sum = scroll + upperBound;
var coords = {};
var stickerCoords = {};
var condition;
for (var i = 0; i < length; i++) {//for begin
coords = getCoords(stickerBlocks[i]);
stickerCoords = getCoords(stickers[i]);
condition = parseInt(stickers[i].style.top) != parseInt(coords.bottom - coords.top - (stickerCoords.bottom - stickerCoords.top) - 1);
if (coords.bottom < sum) {
continue;
}
if (coords.top < sum && stickers[i].style.position != 'fixed' && condition) {
stickers[i].style.position = 'fixed';
stickers[i].style.top = upperBound + 'px';
}
coords = getCoords(stickerBlocks[i]);
stickerCoords = getCoords(stickers[i]);
if (stickerCoords.bottom > coords.bottom) {
stickers[i].style.position = 'relative';
stickers[i].style.top = parseInt(coords.bottom - coords.top - (stickerCoords.bottom - stickerCoords.top) - 1) + 'px';
}
coords = getCoords(stickerBlocks[i]);
stickerCoords = getCoords(stickers[i]);
if (stickerCoords.top < coords.top && i != 0) {
stickers[i].style.position = 'relative';
stickers[i].style.top = 0 + 'px';
}
condition = parseInt(stickers[i].style.top) == parseInt(coords.bottom - coords.top - (stickerCoords.bottom - stickerCoords.top) - 1);
coords = getCoords(stickerBlocks[i]);
stickerCoords = getCoords(stickers[i]);
if (stickerCoords.top > sum && condition) {
stickers[i].style.position = 'fixed';
stickers[i].style.top = upperBound + 'px';
break;
}
}//for end
}//onscroll end
}//onload end
</script>
</body>
</html>