Как настроить смартфоны и ПК. Информационный портал

Загрузка страницы по мере скроллинга. Крути меня полностью

Всем привет. Сегодня хочу поговорить с вами о том, как организовать «ленивую загрузку» контента на посадочных страницах.

Часто, ее еще называют «бесконечной прокруткой». Наверняка вы видели подобный эффект, когда контент изначально не присутствует на сайте, а по мере прокрутки страницы он плавно подгружается.

Давненько уже написали в раздел «Ваши предложения», с просьбой написать статью о том, как реализовать такой эффект:


Вот и решил, заняться реализацией. Спасибо, что подкидываете идеи. Приступим…



Как и в большинстве случаев, начинаем с того, что подключаем библиотеку jQuery:

А сейчас нужно немножко отвлечься и я объясню вам суть метода. Все это затевается для того, чтобы не грузить все элементы сайта (ваше портфолио или отзывы), а подгружать их по мере необходимости. Например, при клике пользователя по кнопке «Показать еще». Таким образом, страница будет грузиться намного быстрее. А теперь суть, при помощи ajax технологии мы будем подгружать нужный элемент (div) и стороннего файла на наш лендинг. Вот так все просто, как в теории, так и на практике, и вы в этом скоро убедитесь.

Теперь давайте создадим основной блок, например, с картинками наших работ. Предположим мы рисуем иконки, и будем подгружать их при клике по кнопке. Я создал такую структуру:

Портфолио Показать еще...

Как видите, все — просто. Но на что нужно обратить внимание? А обратить внимание нужно на div с id=»smartPortfolio», id=»moreButton» и id=»loadingDiv», так как они используются в скрипте, который и помогает нам загружать контент с других страниц. SmartPortfolio — это «контейнер» для нашего портфолио. MoreButton — это будет наша кнопка, при клике на которую загружается еще одна часть портфолио. LoadingDiv — область, в которую будет выводиться текст, когда портфолио будет полностью открыто, либо возникнет какая-нибудь ошибка.

Например, часть из читателей все равно будет пытаться тестировать этот скрипт не на сервере, а просто откроют индексный файл в браузере. В таком случае они увидят сообщение об ошибке. Кроме того, при совсем медленном соединении, на загрузку файлов может понадобиться время, и чтобы пользователь понимал, что процесс идет, можно вписать туда сообщение, что идет загрузка данных или поместить (картинку, индикатор прогресса или еще что-то).

Сам скрипт я не писал, а нашел на одном из сайтов, автор указан в исходнике, кому интересно — посмотрите. Так как он не слишком большого размера, то приведу его весь, но если вы планируете использовать такие же названия айдишников и пути к файлам, как у меня, то можете даже не заглядывать в него, а просто подключить перед закрывающимся тегом body (в футере).

Для тех, кто планирует вносить правки вот сам скрипт:

Var lazyload = lazyload || {}; (function($, lazyload) { "use strict"; var page = 2, buttonId = "#moreButton", loadingId = "#loadingDiv", container = "#smartPortfolio"; lazyload.load = function() { var url = "./pages/" + page + ".html"; $(buttonId).hide(); $(loadingId).show(); $.ajax({ url: url, success: function(response) { if (!response || response.trim() == "NONE") { $(buttonId).fadeOut(); $(loadingId).text("Портфолио полностью загружено"); return; } appendContests(response); }, error: function(response) { $(loadingId).text("К сожалению, возникла какая-то ошибка при запросе. Пожалуйста, обновите страницу."); } }); }; var appendContests = function(response) { var id = $(buttonId); $(buttonId).show(); $(loadingId).hide(); $(response).appendTo($(container)); page += 1; }; })(jQuery, lazyload);

Итак, теперь стоит поговорить о тех файлах, из которых мы будем подгружать информацию. Скрипт предполагает, что это будут файла с именами 2.html…5.html и т.д. В которых лежит наша информация. Например, у меня первым подгружается файл 2.html и он имеет такое содержимое:

В моей структуре сайта, страницы из которых будет браться информация для последующей загрузке при клике, лежит в папке pages. Там три файла, два из которых заполнены, а последний — пустой. Это предполагает логика скрипта.

Путь в скрипте указан следующим образом:

Var url = "./pages/" + page + ".html";

Если вы планируете использовать другой путь, не забудьте заменить его в скрипте. Кроме того, если вы использовали другие айдишники, то и их придется переопределить в скрипте. Вот тут:

ButtonId = "#moreButton", loadingId = "#loadingDiv", container = "#smartPortfolio";

И, как я уже говорил, перед закрывающимся тегом body подключаем сам скрипт:

Вот так на landing page можно реализовать «ленивую загрузку». Присылайте еще темы, на которые вы хотели-бы почитать статью на блоге. По мере возможности буду стараться публиковать не запланированный материал, а тот, о котором спрашиваете вы в разделе «Ваши предложения». А на сегодня — все. Пока!

Песочница

рекрут 9 февраля 2013 в 21:42 Крути меня полностью. Адаптивный макет с бесконечной прокруткой
  • Чулан *

Не так давно столкнулся с задачей:
- Верстка адаптивного макета. При ресайзе окна, элементы на странице масштабируются до определенной ширины. Если ширина меньше минимальной, количество элементов в ряду становится меньше, в то же время заполняя весь экран по ширине. Смысл понятен - страница должна смотреться на любом мониторе, в т.ч. на мобильных устройствах.
- Подгрузка содержимого происходит при прокрутке страницы, так что выводится лишь часть контента, остальной подгружается по мере прокрутки вниз (аналог стены ВК).
- Появление элементов на странице происходит по очереди, плавным увеличением прозрачности каждого элемента. После того как первый элемент стал непрозрачным, эффект применяется к следующему элементу… и так для всех.

Готового решения не нашел, все пришлось писать с нуля. Возможно вся эта фича бесполезна, но если вдруг кому пригодится - юзаем, тестируем, наслаждаемся:

HTML . Для тестирования по-быстрому сверстал очень простой макет. Чтобы долго не заморачиваться со стилями, подключил bootstrap. Вот такая разметка:
Хеллоу ворлд! // В принципе, инициализировать класс можно и не здесь, и без параметров. Об этом далее. // контейнер, куда выводятся все элементы. // В нашем случае каждый item - отдельный элемент на странице. Их выведем много. // ... много-много item // Делаем очистку, т.к. у наших item"ов float:left

CSS . Тут все просто до безобразия. Подключил bootstrap, задал несколько стилей для контента - и вперед!
@import url("bootstrap.css"); body { background: #000; } section.container { position: absolute; top: 50px; bottom: 50px; width: 100%; overflow: auto;} section.container > section.item { position: relative; float: left; margin: 0; padding: 0; height: 140px; overflow: hidden;} section.container > section.item > img {width: 100%;}

JS . Вот тут уже интересно. Изначально писал функции по-отдельности, потом, когда все заработало обьединил их в один класс
GALLERY = { // задаем дефолтные параметры, которые можно будет переопределить при инициализации. container: "section.container", // родительский контейнер item: "section.item", // отдельный элемент галереи img: "section.item > img.hidden", // изображение, которое мы будем изначально "прятать" interval: 200, // задержка эффекта прозрачности count: 5, // количество добавляемых элементов init: function(params) { var _self = this; // Переопределение параметров (если такие переданы. Если нет - используем по умолчанию.) if(params != undefined){ for (var key in params) { _self = params; } } return _self.setUp(); }, setUp: function() { var _self = this; // Вешаем обработчики событий. В нашем случае такие нужны окну (ресайз) $(window).bind("resize", function(){ _self.adjust(); }); // ... на загрузку страницы $(document).ready(function(){ _self.adjust(); _self.play(); }); // ... на прокутку в родительском блоке $(_self.container).bind("scroll", function(){ _self.checkScroll(); }); }, // подгоняем ширину и количество элементов в ряду, зависимо от размера окна adjust: function() { var _self = this; var outWidth = $(_self.container).width(); var outHeight = $(_self.container).height(); var minWidth = 220; var cnt = Math.floor(outWidth / minWidth); var itemWidth = outWidth / cnt; $(_self.item).css({ "width" : itemWidth + "px" }); }, // Запускаем эффект постепенного появления элементов. Маленький нюанс: Класс hidden // для изображения нужен не за тем чтобы его прятать (это будет делать метод ниже), а для поиска // первого элемента при каждом обновлении контента. Цикл метода play() проходит // по всем изображениям с классом hidden (изначально такой есть у всех), после применения // эффекта fadeIn(), удаляя класс. Таким образом, при подгрузке нового контента, цикл начинается // не с первого элемента, а с первого подгруженного. // Впервые столкнулся с использованием метода queue(). play: function() { var _self = this; var items = $(_self.container).find(_self.img); $(items).each(function(i) { var cur = $(this).hide(); $(document).queue("myQueue", function(n) { cur.removeClass("hidden").fadeIn(_self.interval, n); }); }); $(document).dequeue("myQueue"); }, // Собственно подгрузка контента. Здесь все просто: отправляем запрос на сервер - получаем // новое содержимое на страницу (если такое есть) и выводим его в самом конце родительского блока load: function() { var _self = this; $.ajax({ url: "/load.php", type: "POST", data: {"count": _self.count}, dataType: "json", success: function(json) { if(json.output) { $(_self.container).children("div.clearfix").before(json.output); _self.adjust(); _self.play(); } } }); }, // Проверяем состояние прокрутки. Если вертикальная прокрутка в родительском блоке // равна максимально возможной - отправляем запрос за новым контентом. // Таким образом, подгрузка содержимого будет выполняться только если мы // докрутили страницу до конца. checkScroll: function() { var _self = this; var scrollH = $(_self.container).prop("scrollHeight"); var scrollT = $(_self.container).prop("scrollTop"); var scrollS = $(_self.container).prop("scrollTop") + $(_self.container).height(); if(scrollS == scrollH) { _self.load(); } } }

PHP . Тут все примитивно, только для тестирования.
$json = array(); $html = ""; $items_on_page = !empty($_POST["count"])? (int)$_POST["count"]: 5; for($i = 0; $i < $items_on_page; $i++) { $html .= ""; } $json["output"] = $html; echo json_encode($json);
Здесь в $_POST передается только один параметр (количество добавляемых блоков), но можно передать дополнительно точку старта, по принципу пагинации. Ее можно получить в JS при помощи:
var items = $(_self.container).find(_self.img); var start = items.length; // и передать в запросе: data: {"count": _self.count, "start": start}, // ... после чего при выборке данных указать..." LIMIT " . (int)$_POST["start"] . ", " . $items_on_page;

Вот такая получилась «пагинация без пагинации», да на резиновой страничке. Рабочий пример здесь.

В 2011 году очень модно было (по-моему, эта мода пошла от Фейсбука) делать у себя на сайтах «бесконечный скроллинг»: это когда пользователь крутит-крутит колесом мыши, и всё новые результаты поиска подгружаются Аяксом внизу страницы, превращая обычный скроллинг в бесконечный и вызывая у столкнувшегося с этим в первый раз пользователя «когнитивный диссонанс».

Также недавно я видел на этом сайте статью, в которой автор выражал своё недовольство «бесконечным скроллингом» и призывал использовать старую добрую «паджинацию».

Я согласен с автором. Я сам - наркоман, и порою сижу за монитором как зачарованный, со стеклянными глазами, кручу-кручу-кручу волшебное колёсико, не в состоянии пойти по делам/на работу/в магазин/поесть/попить/в туалет, и кручу я его с одной единственной мыслью: «Ну когдааа же вы все уже закончитесь?!» (что поделаешь - я привык доводить дела до конца).

Однажды утром я встал и твёрдо решил: «Хватит это терпеть!».

Представляю вам свой небольшой скрипт , который я на днях написал для своей «социальной сети» (с блекджеком и шлюхами).

Чтобы посмотреть демо, скачайте архив , и запустите файл «test/test.html».

Какие нововведения предлагает этот скрипт:

Поскольку основной «скроллбар» они превратили непонятно во что, нам нужно вернуть нормальный «скроллбар», что мы и сделали, нарисовав серую полоску в правой части страницы, сразу слева от обычного «скроллбара».

То, докуда дошла эта полоска сверху - это сколько результатов выборки мы уже пролистали. Вообще, эта полоска как бы чёрная. Там, где она серая - это место во всей выборке, где мы находимся сейчас.

Обратите также внимание на то, что адрес страницы меняется во время прокрутки. Таким образом, вы можете сегодня вечером пролистать половину, добавить страницу в закладки, выключить компьютер, пойти спать, проснуться утром, включить компьютер, зайти на страницу, добавленную вами вчера перед сном в закладки, и продолжить листать с того самого места, на котором вы остановились. И, более того, вы сможете листать с этого места не только вперёд, но и назад.

И по поводу навигации на любую нужную страницу: попасть на любую страницу можно и здесь - просто подставьте в адрес веб страницы номер нужной вам страницы выборки. Поскольку человекопонятные url"ы сейчас являются стандартом, это должно быть годным решением.

Этот скрипт, очевидно, не является чем-то высеченным в граните, и я сам, встав сегодня с утра, переписал его половину. Тем не менее, работоспособность вроде как стабильная, и проверено в последних версиях Chrome и FireFox. Сразу скажу: не гонюсь за «кроссбраузерностью» - её всегда можно будет допилить, если кто-то захочет использовать этот скрипт на своём «кроссбраузерном» сайте.

Вроде как всё, демо говорит само за себя. Пост провоцирует комментарии.

Что ещё можно сделать (на основе комментариев):

При клике в любое место полоски - переходить на соответствующую страницу выборки.

Убирать страницы данных с верха веб страницы, когда данных на веб странице становится слишком много (чтобы не тормозило).

Примеры улучшенного «бесконечного скроллинга».

Что-то давненько я не публиковал никакого кода. Сегодня я исправлю ситуацию и дам несколько полезных сниппетов на jQuery, которые обязательно вам пригодятся на ваших сайтах.


Я не буду вдаваться в теорию, вся документация по jQuery есть на официальном сайте библиотеки. Я лишь напомню, что, такое jQuery.

jQuery - это библиотека JavaScript, фокусирующаяся на взаимодействии JavaScript и HTML. Библиотека jQuery помогает легко получать доступ к любому элементу DOM, обращаться к атрибутам и содержимому элементов DOM, манипулировать ими. Также библиотека jQuery предоставляет удобный API для работы с AJAX.

Итак, поехали!

1. Плавная прокрутка к началу страницы

Без нее уже не обходится ни один сайт. Всего лишь 4 строчки кода позволят вашим посетителям в один клик плавно пркрутить всю страницу вверх.

$("a").click(function() { $("html, body").animate({ scrollTop: 0 }, "slow"); return false; });

2. Дублируем заголовки таблиц

Чтобы улучшить восприятие и читабельность ваших таблиц, можно продублировать их заголовки снизу под таблицей. Казалось бы мелочь, но это очень удобно в сложных и больших таблицах, которые не умещаются в один экран.

Var $tfoot = $(""); $($("thead").clone(true, true).children().get().reverse()).each(function(){ $tfoot.append($(this)); }); $tfoot.insertAfter("table thead");

3. Подгрузка внешних данных

С помощью jQuery очень легко подгружать на веб-страницы внешний контент. Его можно вывести прямо в блок DIV, как в примере ниже.

$("#content").load("somefile.html", function(response, status, xhr) { // error handling if(status == "error") { $("#content").html("An error occured: " + xhr.status + " " + xhr.statusText); } });

4. Одинаковая высота колонок

Известно, что выровнять блоки по высоте стандартными средствами HTML и CSS не так-то просто. Всего несколько строк кода ниже позволит вам сделать высоту всех блоков равной высоте большего блока.

var maxheight = 0; $("div.col").each(function(){ if($(this).height() > maxheight) { maxheight = $(this).height(); } }); $("div.col").height(maxheight); 5. Табличная зебра

Как известно, восприятие и читабельность таблицы будет заметно выше если сделать разноцветное чередование строк. Это очень легко реализуется на jQuery.

$(document).ready(function(){ $("table tr:even").addClass("stripe"); });

6. Частичное обновление страницы

С помощью jQuery очень просто реализовать блочное (частичное) обновление страницы. К примеру, код ниже позволит вам каждые 10 секунд автоматически обновлять блок #refresh.

SetInterval(function() { $("#refresh").load(location.href+" #refresh>*",""); }, 10000); // milliseconds to wait

7. Предзагрузка изображений

Данный код позволяет осуществлять загрузку изображений в фоновом режиме без подгрузок в процессе просмотра страницы. Просто перечислите в 7 строке необходимые вам для предзагрузки изображения.

$.preloadImages = function() { for(var i = 0; i maxWidth){ ratio = maxWidth / width; $(this).css("width", maxWidth); $(this).css("height", height * ratio); height = height * ratio; } var width = $(this).width(); var height = $(this).height(); if(height > maxHeight){ ratio = maxHeight / height; $(this).css("height", maxHeight); $(this).css("width", width * ratio); width = width * ratio; } }); //$("#contentpage img").show(); // IMAGE RESIZE });

12. Подгрузка контента при прокрутке страницу вниз

Чаще этот прием называют как бесконечный скролл. Контент подгружается по мере прокрутки пользователем страницы. Это достаточно просто реализовать с помощью кода ниже.

Var loading = false; $(window).scroll(function(){ if((($(window).scrollTop()+$(window).height())+250)>=$(document).height()){ if(loading == false){ loading = true; $("#loadingbar").css("display","block"); $.get("load.php?start="+$("#loaded_max").val(), function(loaded){ $("body").append(loaded); $("#loaded_max").val(parseInt($("#loaded_max").val())+50); $("#loadingbar").css("display","none"); loading = false; }); } } }); $(document).ready(function() { $("#loaded_max").val(50); });

13. Проверка загрузки изображения

Часто бывает нужно проверить загружено изображение в данный момент или нет. И в этом снова нам поможет jQuery.

Var imgsrc = "img/image1.png"; $("").load(function () { alert("image loaded"); }).error(function () { alert("error loading image"); }).attr("src", imgsrc);

14. Сортировка по-алфавиту

Если вам нужна динамическая сортировка списка по-алфавиту, вам обязательно поможет этот небольшой сниппет.

$(function() { $.fn.sortList = function() { var mylist = $(this); var listitems = $("li", mylist).get(); listitems.sort(function(a, b) { var compA = $(a).text().toUpperCase(); var compB = $(b).text().toUpperCase(); return (compA < compB) ? -1: 1; }); $.each(listitems, function(i, itm) { mylist.append(itm); }); } $("ul#demoOne").sortList(); });

Сохраните - пригодится.

Всё самое новое и интересное из мира Вордпресс в моём Телеграм-канале . Подписываемся!

Лучшие статьи по теме