Событие происходит, когда элемент прокручивается. Его могут генерировать только прокручиваемые элементы.
При прокрутке окна срабатывает событие window.onscroll.
Например, следующая функция при прокрутке окна выдает количество прокрученных пикселей:
window.onscroll = function() {
var scrolled = window.pageYOffset || document.documentElement.scrollTop;
document.getElementById('showScroll').innerHTML = scrolled + 'px';
}
В действии:
Текущая прокрутка = прокрутите окно
Более подробно о том, как получить значение прокрутки или прокрутить документ — читайте в статье Размеры и прокрутка элементов.
Сделайте так, чтобы при прокрутке ниже элемента #avatar (картинка с Винни-Пухом) — он продолжал показываться в левом-верхнем углу.
При прокрутке вверх — должен возвращаться на обычное место.
Прокрутите вниз, чтобы увидеть:
Открыть в новом окне
Исходный документ: tutorial/browser/events/scroll-position-src/index.html.
Создайте кнопку навигации, которая помогает при прокрутке страницы.
Работать должна следующим образом:
- Пока страница промотана меньше чем на высоту экрана вниз — кнопка не видна.
- При промотке страницы вниз больше, чем на высоту экрана, появляется кнопка «стрелка вверх». При нажатии на нее страница запоминает текущую прокрутку и прыгает вверх, а кнопка меняется на «стрелка вниз» и остается такой, пока посетитель не прокрутит вниз больше, чем один экран, после чего вновь изменится на «стрелка вверх».
- Нажатие на «стрелка вниз» отправляет обратно на запомненную позицию.
Должен получиться удобный навигационный помощник.
Посмотрите, как оно должно работать, в ифрейме ниже. Прокрутите ифрейм, навигационная стрелка появится слева.
Исходный документ с кнопкой: tutorial/browser/dom/updown-src/index.html.
Добавим в документ DIV с кнопкой:
<div id="updown"></div>
Сама кнопка должна иметь «position:fixed».
#updown {
position: fixed;
top: 30px;
left: 10px;
cursor: pointer;
}
Кнопка является CSS-спрайтом, поэтому мы дополнительно добавляем ей размер и два состояния:
#updown {
height: 9px;
width: 14px;
position: fixed;
top: 30px;
left: 10px;
cursor: pointer;
}
#updown.up {
background: url(updown.gif) left top;
}
#updown.down {
background: url(updown.gif) left -9px;
}
Для решения необходимо аккуратно разобрать все возможные состояния кнопки и указать, что делать при каждом.
Состояние — это просто класс элемента: up/down или пустая строка, если кнопка не видна.
При прокрутке состояния меняются следующим образом:
window.onscroll = function() {
var pageY = window.pageYOffset || document.documentElement.scrollTop;
var innerHeight = document.documentElement.clientHeight;
switch(updownElem.className) {
case '':
if (pageY > innerHeight) {
updownElem.className = 'up';
}
break;
case 'up':
if (pageY < innerHeight) {
updownElem.className = '';
}
break;
case 'down':
if (pageY > innerHeight) {
updownElem.className = 'up';
}
break;
}
}
При клике:
var pageYLabel = 0;
updownElem.onclick = function() {
var pageY = window.pageYOffset || document.documentElement.scrollTop;
switch(this.className) {
case 'up':
pageYLabel = pageY;
window.scrollTo(0, 0);
this.className = 'down';
break;
case 'down':
window.scrollTo(0, pageYLabel);
this.className = 'up';
}
}
Полное решение: tutorial/browser/dom/updown/index.html.
Задача, которая описана ниже, демонстрирует результативный метод оптимизации страницы.
С целью экономии трафика и более быстрой загрузки страницы, изображения на ней заменяются на «макеты».
Вместо такого изображения:
<img src="yozhik.jpg" width="128" height="128">
Стоит вот такое:
<img *!*src="1.gif"*/!* width="128" height="128" *!*realsrc="yozhik.jpg"*/!*>
То есть, настоящий URL находится в атрибуте realsrc (название атрибута можно выбрать любое). А в src поставлен серый GIF размера 1x1, и так как width/height правильные, то он растягивается, так что вместо изображения виден серый прямоугольник.
При этом, чтобы браузер загрузил изображение, нужно заменить значение src на то, которое находится в realsrc.
Если страница большая, то замена больших изображений на такие макеты существенно убыстряет полную загрузку страницы. Это особенно заметно в случае, когда на странице много анонсов новостей с картинками или изображений товаров, из которых многие находятся за пределами прокрутки.
Кроме того, для мобильных устройств JavaScript может подставлять URL уменьшенного варианта картинки.
Напишите код, который при прокрутке окна загружает ставшие видимыми изображения. То есть, как только изображение попало в видимую часть документа — в src нужно прописать правильный URL из realsrc.
Работать должно так: открыть работающую страницу в новом окне.
- При начальной загрузке часть изображений становятся видимыми сразу, до прокрутки. Код должен это учитывать.
- Часть изображений могут быть изначально обычными, без
realsrc. Их код не должен трогать вообще. - Также код не должен перегружать уже показанное изображение.
Дополнительно: расширьте код, чтобы загружались изображения не только видимые сейчас, но и на страницу вперед и назад от текущего места.
Исходный документ с макетами и изображениями: tutorial/browser/dom/lazyimg-src/index.html.
P.S. Вам понадобится функция определения координат элемента. Она называется getOffsetRect и возвращает координаты верхнего-левого угла. Находится в исходном документе выше в файле lib.js.
P.P.S. Страница прокручивается только вверх или вниз, горизонтальной прокрутки нет.
Функция должна по текущей прокрутке определять, какие изображения видимы, и загружать их.
Она должна срабатывать не только при прокрутке, но и при загрузке. Вполне достаточно для этого — указать ее вызов в скрипте под страницей, вот так:
... страница ...
function showVisible() {
var imgs = document.getElementsByTagName('img');
for(var i=0; i<imgs.length; i++) {
var img = imgs[i];
var realsrc = img.getAttribute('realsrc');
if (!realsrc) continue;
if (*!*isVisible(img)*/!*) {
img.src = realsrc;
img.setAttribute('realsrc', '');
}
}
}
*!*
showVisible();
window.onscroll = showVisible;
*/!*
При запуске функция ищет все видимые картинки с realsrc и перемещает значение realsrc в src. Обратите внимание, т.к. атрибут realsrc нестандартный, то для доступа к нему мы используем get/setAttribute. А src — стандартный, поэтому можно обратиться по DOM-свойству.
Функция проверки видимости isVisible(elem) получает координаты текущей видимой области и сравнивает их с элементом.
Для видимости достаточно, чтобы координаты верхней(или нижней) границы элемента находились между границами видимой области.
Как получить метрики элемента и страницы, описано в статье Размеры и прокрутка элементов.
Итоговая функция:
function isVisible(elem) {
var coords = getOffsetRect(elem);
var windowTop = window.pageYOffset ||
document.documentElement.scrollTop;
var windowBottom = windowTop +
document.documentElement.clientHeight;
coords.bottom = coords.top + elem.offsetHeight;
// верхняя граница elem в пределах видимости
// ИЛИ нижняя граница видима
var topVisible = coords.top > windowTop
&& coords.top < windowBottom;
var bottomVisible = coords.bottom < windowBottom
&& coords.bottom > windowTop;
return topVisible || bottomVisible;
}
В решении также указан вариант с isVisible, который расширяет область видимости на +-1 страницу (высота страницы — document.documentElement.clientHeight).
Решение: tutorial/browser/dom/lazyimg/index.html.
Комментарии
- Приветствуются комментарии, содержащие дополнения и вопросы по статье, и ответы на них.
- Если ваш комментарий касается задачи -- откройте её в отдельном окне и напишите там.
- Комментарии без смысла, с рекламой или не о статье вообще - удаляются.