Deff, я взял за основу несколько другой способ, его уж и закончу))
<!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;
}
.left {
width: 500px;
background: lightgray;
border: 1px solid black;
}
.right {
background: gray;
border: 1px solid black;
width: 200px;
vertical-align: top;
}
.sticker {
position: relative;
background: whitesmoke;
height: 100px;
}
</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="left">';
for (var k = 0; k < 31; k++) {
inner += 'таблица ' + i + '; строка ' + j + '<br>';
}
str += inner + '</td><td class="right"><div class="sticker">sticker ' + i + ' - ' + j + '</div></td></tr>';
inner = '';
}
str += '</table>';
}
content.innerHTML = str;
//функция получения координат элемента относительно документа
var getCoords = function (element) {//getCoords begin
var elementRect = element.getBoundingClientRect();
var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var clientLeft = document.documentElement.clientLeft || document.body.clientLeft || 0;
var clientTop = document.documentElement.clientTop || document.body.clientTop || 0;
var left = elementRect.left + scrollLeft - clientLeft;
var top = elementRect.top + scrollTop - clientTop;
var bottom = elementRect.bottom + scrollTop - clientTop;
var obj = {
left: Math.round(left),
top: Math.round(top),
bottom: Math.round(bottom),
}
return obj;
}//getCoords end
//функция получения координат всех элементов
var getAllCoords = function (collection) {//getAllCoords begin
var allCoords = [];
for (var i = 0; i < length; i++) {
allCoords[i] = getCoords(collection[i]);
}
return allCoords;
}//getAllCoords 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;
}//if end
}//getElementsByClassName end
//необходимые переменные
var leftBlocks = content.getElementsByClassName('left'); //колллекция блоков слева
var rightBlocks = content.getElementsByClassName('right');//коллекция блоков справа
var stickers = content.getElementsByClassName('sticker');//коллекция липких блоков
var length = leftBlocks.length; // = rightBlocks.length; //= stickers.length;
//получаем координаты всех элементов слева
var allCoords = getAllCoords(leftBlocks);
var upperBound = allCoords[0].top;//верхняя граница
//пересчитываем координаты при масштабировании страницы
window.onresize = function () {
allCoords = getAllCoords(leftBlocks);
upperBound = allCoords[0].top;
}
//скроллинг клавишами++++++++++++++++++++++++++++++++++++++++++++++++++++++
document.onkeyup = function (e) {//onkeyup begin
var e = e || window.event; //для IE
//получаем прокрутку
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
//функция получения номера элемента на верхней границе для движения вверх
var getNUp = function(coords, boundary) {//getNUp begin
//расстояние от начала документа до верхней границы
var sum = scrollTop + boundary;
for (var i = 0; i < length; i++) {//for begin
//если элемент ниже верхней границы и не первый, возвращаем номер предыдущего элемента
if (coords[i].top >= sum && i != 0) {
return (i - 1);
} else
//иначе, если элемент пересекает верхнюю границу, возвращаем его номер
if (coords[i].bottom > sum) {
return i;
}
}//for end
//если дошли, то возвращаем номер самого элемента (он будет последним при полной прокрутке)
return (i - 1);
}//getNUp end
//функция получения номера элемента на верхней границе для движения вниз
var getNDown = function (coords, boundary) {//getNDown begin
//расстояние от начала документа до верхней границы
var sum = scrollTop + boundary;
for (var i = 0; i < length; i++) {//for begin
//если элемент пересекает верхнюю границу, возвращаем номер последующего элемента, если он не последний
if (coords[i].bottom > sum && i != length - 1) {
return (i + 1);
} else //иначе, если элемент ниже верхней границы, возвращаем его номер
if (coords[i].top > sum) {
return i; //(i - 1), так как i в цикле увеличивается при выходе
}
}//for end
//если дошли, то возвращаем номер самого элемента (он будет последним при полной прокрутке)
return (i - 1);//
}//getNDown end
//проверяем клавиши и получаем номер нужного блока
var n = 0;
switch ( e.keyCode ) {
case 65: {//нажата клавиша "вверх" (Ф, ф - рус., A, a - eng.)
var n = getNUp(allCoords, upperBound);
break;
}
case 83: {//нажата клавиша "вниз" (В, в - рус., S, s - eng.)
var n = getNDown(allCoords, upperBound);
break;
}
default: return; //вышли, если не та клавиша
}//switch end
//если дошли, то прокрутили страницу, поместив начало блока на верхнюю границу
window.scrollTo(0, allCoords[n].top - upperBound);
}//onkeyup end
//липкие блоки+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
window.onscroll = function () {//onscroll begin
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var sum = scrollTop + upperBound;
var stickerCoords = {};
//получаем липкий блок и задаём ему нужные координаты относительно родительского контейнера
for (var i = 0; i < length; i++) {//for begin
stickerCoords = getCoords(stickers[i]);
//если липкий блок в границах своего контейнера, то выровнять липкий блок по верхней границе
if (stickerCoords.top >= allCoords[i].top && stickerCoords.bottom <= allCoords[i].bottom ) {
stickers[i].style.top = sum - allCoords[i].top + 'px';
//return;
}
//корректирование предыдущего действия
stickerCoords = getCoords(stickers[i]);
//если липкий блок зашёл за верхнюю границу своего контейнера, то выровнять по верхнему краю своего контейнера
if (stickerCoords.top < allCoords[i].top) {
stickers[i].style.top = 0 + 'px';
}
//если контейнер липкого блока ниже верхней границы, то выровнять его липкий блок по его верхнему краю
if (allCoords[i].top > sum) {
stickers[i].style.top = 0 + 'px';
return;
}
/*
if (window.getComputedStyle) {
var stickerMarginBottom = parseInt(getComputedStyle(stickers[i], null).marginBottom);
} else {
var stickerMarginBottom = stickers[i].currentStyle.marginBottom;
}
*/
//если липкий блок зашёл за нижнюю границу своего контейнера, то выровнять по нижнему краю своего контейнера
if (stickerCoords.bottom > allCoords[i].bottom) {
stickers[i].style.top = (allCoords[i].bottom - allCoords[i].top) - (stickerCoords.bottom - stickerCoords.top) - 2 + 'px';
}
}//for end
}//onscroll end
}//onload end
</script>
</body>
</html>