09.06.2012, 19:39
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Скроллинг клавишами и липкие блоки
Решая на чистом js задачу скроллинга клавишами, а также липких блоков из Перемещение блока при скроллинге столкнулся с рядом проблем.
Основа: набор таблиц, в каждой из которой набор строк, в первой ячейке каждой строки произвольное содержимое, вторая ячейка - контейнер для липкого блока.
Липкие блоки: (см ссылку).
Скроллинг: по нажатию символьных клавиш, которые символизируют "вверх" и "вниз" последовательно перемещаться по ячейкам всей совокупности таблиц.
Взял за основу метод document.elementFromPoint(x, y), с помощью которого получаю блок и далее работаю с ним (либо перемещаю к нужной ячейке при скроллинге, либо контролирую положение соответствующего липкого блока).
По скроллингу: перемещения производятся, но в некоторые моменты document.elementFromPoint(x, y) возвращает не нужный блок, а саму таблицу (даже если не учитывать, что специально прокрутили, чтобы попасть в margin между ячейками, тоже пока не соображу как это обойти), хотя вроде бы чётко смещаю при каждом нажатии клавиши левый верхний угол блока в точку, в которой находился первый блок при загрузке страницы.
По липким блокам: задача вроде бы тоже не сложная, но не получается cформировать условия (совладать с координатами, рисование пока не помогает).
Может быть у кого есть соображения на эту тему по моей логике решения (необходимый, на мой взгляд, функционал я включил в код), или может быть альтернативные подходы к решению этих задач.
<!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 obj = {
left: Math.round(left), top: Math.round(top),
scrollTop: Math.round(scrollTop), scrollLeft: Math.round(scrollLeft),
clientLeft: Math.round(clientLeft), clientTop: Math.round(clientTop)
}
return obj;
}//getCoords end
//функция получения номера по элементу, если элемент не в коллекции -1
var getN = function (element, collection) {//getN begin
for (var i = 0; i < length; i++) {
if (element == collection[i]) {
return i
}
}
return -1;
}//getN end
//функция получения элемента по номеру, если нет такого элемента -1
var getElement = function (n, collection) {//getElement begin
for (var i = 0; i < length; i++) {
if (collection[i] == collection[n]) {
return collection[i];
}
}
return -1;
}//getElement 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 firstLeft = leftBlocks[0]; //первый элемент слева
//его координаты - точка отсчёта
var upperBound = getCoords(leftBlocks[0]).top;//верхняя граница
var leftBound = getCoords(leftBlocks[0]).left; //левая граница
var lastLeft = leftBlocks[length - 1]; //последний элемент слева
var lastLeftCoords = getCoords(lastLeft); //его координаты
//скроллинг клавишами++++++++++++++++++++++++++++++++++++++++++++++++++++++
document.onkeyup = function (e) {//onkeyup begin
var e = e || window.event; //для IE
//получаем элемент на верхней границе и его параметры
var element = document.elementFromPoint(leftBound, upperBound);
/****************************************************
вот в этих двух функциях getToUp и getToDown не получается заложить
необходиму логику решения***********************************/
var getToUp = function (element) {//getToUp begin
var n = getN(element, leftBlocks);
var coords = getCoords(element);
if ( n != -1 ) {//если элемент действительно тот //if begin
//если элемент пересекает верхнюю границу
if ( coords.top < coords.scrollTop + upperBound ) {
return element; //возвращаем сам элемент
} else if ( n != 0 ) {
return element = getElement(n - 1, leftBlocks);//возвращаем предыдущий элемент, если он не первый
}
} else {//если элемент не тот //if else
if ( coords.scrollTop > upperBound) {
return element = firstLeft;//возвращаем первый элемент
} else {
return element = lastLeft;//возвращаем последний элемент
}
}//if end
}//getToUp end
var getToDown = function (element) {//getToDown begin
var n = getN(element, leftBlocks);
var coords = getCoords(element);
if ( n != -1 ) { //if begin
if ( coords.top < coords.scrollTop + upperBound && n != length ) {
return element; //возвращаем последующий элемент, если он не последний
} else {
return element;//возвращаем сам элемент
}
} else {//if else
if ( coords.scrollTop > upperBound) {
//return element = ;
} else {
//return element = ;
}
}//if end
}//getToDown end
//проверяем клавиши и получаем нужный блок
switch ( e.keyCode ) {
case 65: {//нажата клавиша "вверх" (Ф, ф - рус., A, a - eng.)
getToUp (element);
break;
}
case 83: {//нажата клавиша "вниз" (В, в - рус., S, s - eng.)
getToDown(element);
break;
}
default: return; //вышли, если не та клавиша
}//switch end
//если дошли, то прокрутили страницу, поместив блок в точку остчёта
window.scrollTo(getCoords(element).left - leftBound, getCoords(element).top - upperBound);
}//onkeyup end
//липкие блоки+++++++++++++++++++++++++++++++++++++++++
window.onscroll = function () {//onscroll begin
//получаем элемент
var element = document.elementFromPoint(leftBound, upperBound);
//var rect = element.getBoundingClientRect();
var n = getN(element, leftBlocks);
var elementCoords = getCoords(element);//координаты элемента относительно документа
var elementHeight = element.clientHeight;//высота элемента
var sticker = getElement(n, stickers);//текущий липкий блок
var stickerCoords = getCoords(sticker);//координаты липкого блока относительно документа
var stickerHeight = sticker.clientHeight;//высота липкого блока
var scroll = elementCoords.scrollTop;//= stickerCoords.scrollTop //величина прокрутки
var scrollAndUpperBound = scroll + upperBound; //величина прокуртки с учётом верхней границы
var displacement = scrollAndUpperBound - elementCoords.top; //величина смещения
//выравнивание по верхней границе
if ( stickerCoords.top < scrollAndUpperBound || stickerCoords.top > scrollAndUpperBound) {
sticker.style.top = displacement + 'px';
}
//получение новых координат
stickerCoords = getCoords(sticker);
scrollAndUpperBound = stickerCoords.scrollTop + upperBound;
elementCoords = getCoords(element);
displacement = scrollAndUpperBound - elementCoords.top;
//выравнивание по нижней границе
if ( stickerCoords.top + stickerHeight >= elementCoords.top + elementHeight ) {
sticker.style.top = elementHeight - stickerHeight + 'px';
} else if (stickerCoords.top > scrollAndUpperBound ) {
sticker.style.top = displacement + 'px';
}
if (element != lastLeft) {
var nextSticker = getElement(n + 1, stickers);
nextSticker.style.top = '0 px';
}
if ( element == firstLeft && displacement == 0 ) {
sticker.style.top = '0 px';
}
}//onscroll end
}//onload end
</script>
</body>
</html>
Последний раз редактировалось bes, 12.06.2012 в 22:28.
|
|
09.06.2012, 23:58
|
|
junior
|
|
Регистрация: 29.11.2011
Сообщений: 3,924
|
|
Сообщение от bes
|
вторая ячейка - контейнер для липкого блока.
|
зачем? div с абсолютным позиционированием, не?
Что надо в целом вообще не понял. Правильно сформулированная задача уже часть решения
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Последний раз редактировалось nerv_, 10.06.2012 в 00:00.
|
|
10.06.2012, 00:29
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
nerv_, посмотрите подредактированный пример, в принципе, хотя пока и коряво, удалось частично решить вторую часть задачи - блоки начали двигаться примерно так как надо, то есть липнуть при прокрутке к нижней части строки меню (тут можно и с position: relative, главное правильно рассчитать координаты, что собственно и не получается).
Насчёт скроллинга клавишами - когда нажимаете клавишу "вверх" должно прокручиваться на предыдущую строку от той, которая в данный момент сразу под строкой меню, "вниз" - на следующую строку, для прокрутки здесь используются клавиши A - вверх, S - вниз.
|
|
10.06.2012, 12:26
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Липкие блоки более-менее работают (в FF наиболее плавно, в хроме и IE видны подёргивания при прокрутке), но остаётся проблема попадания на нужный блок при помощи document.elementFromPoint(x, y).
Кто-нибудь знает как отследить ближайший блок, если этот метод выдал в качестве элемента, например, не ячейку таблицы, а саму таблицу (например, когда попал в margin между ячейками)?
Специально стал использовал document.elementFromPoint(x, y), чтобы обойтись без цикла, но при таком раскладе проще будет всё рассчитать, если за основу поиска взять именно цикл, а не этот метод. Может быть можно как-нибудь обойтись без цикла?
|
|
10.06.2012, 13:00
|
|
junior
|
|
Регистрация: 29.11.2011
Сообщений: 3,924
|
|
bes, добрый день
obj = {
left: Math.round(left), top: Math.round(top),
scrollTop: Math.round(scrollTop), scrollLeft: Math.round(scrollLeft),
clientLeft: Math.round(clientLeft), clientTop: Math.round(clientTop)
}
obj - глобальная переменная
getN = function (element, collection) {//getN begin
getN - глобальная
getElement = function (n, collection) {//getElement begin
getElement - глобальная
getCoords = function (element) {//getCoords begin
getCoords - глобальная
Дальше продолжать? )
Сообщение от bes
|
главное правильно рассчитать координаты, что собственно и не получается
|
Кстати в IE8 не работает. При загрузки страницы один раз вычисляешь положение каждого блока (при ресайзе перевычисляешь), при скроллине смотришь, какой блок ближе (первое, что приходит в голову)
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
|
|
10.06.2012, 13:30
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
nerv_, спасибо, подправил, попробую и этот способ.
В IE8 не работает из-за getElementsByClassName().
|
|
10.06.2012, 14:14
|
без статуса
|
|
Регистрация: 25.05.2012
Сообщений: 8,219
|
|
bes,
Мож стоит типо:
1. Выяснем, какие блоки находяться в зоне видимости,
2. Тестируем расстояние нижнего края верхнего видимого блока(посколь их может быть и два) от
верха экрана, ежели оно менее его высоты, даем липкому блоку спецфическое id и позицию fixed , ежели оно менее высоты липкого блока, вычислем его координаты и закрепляем позицией absolute убираем id
id - удобно для ie
|
|
11.06.2012, 13:15
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
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>
Последний раз редактировалось bes, 12.06.2012 в 22:33.
|
|
11.06.2012, 20:50
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Подредактировал предыдущий пример, теперь рабочий (в IE<9 не будет работать из-за getElementsByClassName и getComputedStyle, тут нужно эмулировать, остальное вроде бы кроссбраузерно).
Лучше сформулировать логику установки координат для липких блоков пока не могу, тут если умные люди подключатся, подскажут, но, главное, работает.
nerv_, Deff, спасибо за помощь и участие.
|
|
12.06.2012, 20:45
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
<!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>
Последний раз редактировалось bes, 15.06.2012 в 23:12.
|
|
|
|