Нескінченний шутер з автоматичним завантаженням контенту

15

Від автора: посторінкова навігація невід’ємний атрибут будь-якого хорошого сайту. Так як зазвичай на сайті виводиться велика кількість різноманітної інформації і вивести все це на одній сторінці – можна, але не бажано, через велике навантаження на сервер і уповільнення роботи сайту в цілому. Тому в даному уроці ми з Вами розглянемо ще один вид посторінкової навігації – нескінченний шутер з автоматичним завантаженням контенту.

Нескінченний шутер з автоматичним завантаженням контентуНескінченний шутер з автоматичним завантаженням контенту

1. Постановка задачі

Отже, давайте розглянемо наступний приклад. Є ось такий сайт, на головній сторінці якого виводяться звичайні статті:

Нескінченний шутер з автоматичним завантаженням контенту

У ньому вже реалізований простий механізм посторінкової навігації, а саме, на кожній сторінці, виводиться рівно 10 статтей (це кількість визначається в конфігураційному файлі). Потім якщо через адресний рядок передати параметр page, з номером сторінки, то будуть відображатися статті відповідні даній сторінці.

Нам необхідно створити так званий нескінченний шутер, тобто, якщо опустити повзунок вертикального скролла в самий низ сторінки – виконається автоматичне завантаження контенту і будуть відображені відповідні статті наступної сторінки. І ці статті будуть як би продовженням контенту всього основного сайту. Далі користувач продовжує читання статей, тим самим знову ж опускає скролл в самий низ сторінки і знову ж буде виконана завантаження контенту. Звичайно, завантажувати контент нам потрібно буде асинхронно, тому ми будемо використовувати метод AJAX.

2. Огляд роботи тестового сайту

Отже, весь вихідний код тестового сайту я в цій статті наводити не буду, так як він досить великий, так і в исходниках до даному уроку Ви зможете їх побачити. Головний файл даного сайту – це index.php, який, власне, і виводить на екран весь вміст цього сайту. Давайте розглянемо фрагмент коду даного сайту, а саме код PHP файлу index.php:

Як Ви бачите, спочатку підключаємо конфігураційний файл, в якому виконується з’єднання з базою даних і визначається константа COUNT_PER_PAGE – кількість статей, які виводяться на одній сторінці. І, файл functions.php – в якому міститься функція отримання статей з бази даних, відповідно до обраної сторінкою (до неї ми ще повернемося).

Далі, власне визначаємо яку сторінку необхідно завантажити (посторінкової навігації, тобто, перевіряємо наявність у суперглобальном масиві GET осередку page, якщо дана клітинка, є і містить у собі числове значення – то ми створюємо змінну $page в яку і записуємо значення. Якщо ж даної клітинки немає, або в ній міститься не числове значення, то в змінну $page – зберігаємо значення 1 (за замовчуванням відображаємо першу сторінку посторінкової навігації). Далі власне викликаємо функцію get_posts(), яка повертає масив з статтями.

Тепер давайте розглянемо файл functions.php:

У базі даних не виявлено таблиці перевірте налаштування

«);
}
if(mysql_num_rows($result) == 0) {
exit(false);
}
$row = array();
for($i = 0; $i

Як Ви бачите функція приймає лише два значення: $page – номер сторінки, яку потрібно відобразити, і $count_per_page – кількість статей відображаються на одній сторінці (звичайно цей параметр можна було і не передавати, а використовувати константу з конфігураційного файлу, але так буде універсальніше). Дана функція виконує SQL запит на вибірку даних з бази даних і що б реалізувати механізм отримання певних статей, у відповідності зі сторінками, у запиті необхідно використовувати інструкцію LIMIT, і задати власне початок вибірки і кількість вибраних статей. Для того що б визначити початок вибірки ми скористаємося наступним виразом:

$start = ($page — 1)*$count_per_page;

Тобто від номера, який ми передаємо параметром цієї функції ми віднімаємо 1 і множимо на кількість статей, які виводяться на одній сторінці посторінкової навігації. Наприклад, якщо ми хочемо відкрити другу сторінку, то що виходить: $page = 2, мінус 1, отримуємо 1, потім множимо на 10 (кількість статей на одній сторінці) і отримуємо 10, значить в інструкцію потрапляє два значення: LIMIT 10,10, що означає вибрати 10 статтей з бази даних, починаючи з 10. Далі виконуємо даний SQL-запит і повертаємо масив зі статтями.

3. Додаємо допоміжний HTML-код

Перед тим як почати писати код, для нескінченного скролла, давайте додамо допоміжний HTML код:

Блок div з класом load необхідний, для індикації процесу відсилання інформації на сервер. Тобто спочатку, даний блок прихований, але коли йде звернення до сервера, даний блок буде відображатися на екрані. На тлі цього блоку буде встановлена анімаційна картинка gif). Відразу ж давайте додамо стилі даного блоку:

.load {
width:100px;
height:60px;
background-image: url(«images/loading2.gif»);
background-position: center bottom;
background-repeat: no-repeat;
text-align: center;
position: fixed;
top: 60%;
left:15%;
display: none;
}

Блок div з класом pager – інформаційний, він потрібен, що б ми з Вами бачили, яка сторінка наразі відображається. Відразу ж давайте додамо стилів до даного блоку (цей блок я просто виведу в довільному місці сайту, так як скоріше всього його взагалі не потрібно показувати користувачеві, але на етапі розробки сценарію він дуже корисний).

.pager {
width:30px;
height:30px;
text-align: center;
position: fixed;
top: 75%;
left:80%;
display: none;
border: 1px solid red;
}

Нескінченний шутер з автоматичним завантаженням контенту

4. Логіка на javaScript

Тепер необхідно написати код на мові javaScript для роботи нескінченного скролла: тому давайте насамперед завантажити бібліотеку jQuery з офіційного сайту і збережемо в папці js. Також створимо порожній файл script.js і також збережемо його в папці js. Обидва ці файлу підключимо до нашого сайту:

Тепер відкриємо файл script.js і додамо в нього наступний код:

$(document).ready(function () {
var page;
var param = location.
search.
slice(location.search.indexOf(‘?’)+1).
split(‘&’);
var result = [];
for(var i = 0; i < param.length;i++) {
var res = param.split(‘=’);
result[res[0]] = res[1];
}
if(result[‘page’]) {
page = result[‘page’];
}
else {
page = 1;
}
$(«.pager).show().text(page);
var block = false;
$(window).scroll(function () {
if($(window).height() + $(window).scrollTop() >= $(document).height() && !block) {
block = true;
$(«.load»).fadeIn(500, function () {
page++;
$.ajax({
url:»index.php»,
type:»GET»,
data:»page=»+page+»&move=1″,
success:function(html) {
if(html) {
$(html).appendTo($(«#posts»)).hide().fadeIn(1000);
$(«.pager).text(page);
}
$(«.load»).fadeOut(500);
block = false;
}
});
});
}
});
});

Отже насамперед необхідно дізнатися чи немає в адресному рядку параметра page з номером поточної сторінки. Для цього ми використовуємо властивість search об’єкта location, яке містить у собі GET параметри передаються через адресний рядок. Але якщо адресна рядок має вигляд: http://localhost/lessons/pager/index.php?page=2&move=4 властивість search містить рядок: ?page=2&move=4.

Отже, використовуючи метод slice, ми з Вами виключимо знак питання з отриманої рядка. І відразу ж, використовуючи метод split розіб’ємо її в масив, який збережемо змінної param. Розбивати звичайно ж будемо за символом &. Тобто в змінно param міститься масив виду:

[0] = «page=2»,
[1] = «move =4»

А нам необхідно отримати значення параметра page. Отже, використовуючи цикл for, створимо масив result, у якого назви клітинок – це назви GET параметрів, а значення – це значення цих GET параметрів:

var result = [];
for(var i = 0; i < param.length;i++) {
var res = param.split(‘=’);
result[res[0]] = res[1];
}

Тепер перевіримо, чи є в масиві result осередок, page, і якщо є, то її значення запишемо в змінну page. Якщо ж даної клітинки немає, то в змінну page зберігаємо значення 1 (за замовчуванням). Далі, виберемо за допомогою jQuery блок з класом pager, відобразимо його на екрані, за допомогою методу show() і додамо вміст даного блоку (текст даного блоку), значення змінної page, використовуючи для цього метод text().

Далі оголосимо змінну block і збережемо в ній значення FALSE. Ця змінна буде використовуватися для блокування скрипта. Тобто якщо в даній змінно буде збережено значення TRUE, значить, робота наступної ділянки коду буде блокована (про який ми з Вами поговоримо далі). Далі слід ось цю ділянку коду:

var block = false;
$(window).scroll(function () {
if($(window).height() + $(window).scrollTop() >= $(document).height() && !block) {
block = true;
$(«.load»).fadeIn(500, function () {
page++;
$.ajax({
url:»index.php»,
type:»GET»,
data:»page=»+page+»&move=1″,
success:function(html) {
if(html) {
$(html).appendTo($(«#posts»)).hide().fadeIn(1000);
$(«.pager).text(page);
}
$(«.load»).fadeOut(500);
block = false;
}
});
});
}
});

Зітріть вибираємо елемент window і викликаємо метод scroll(). Який задає функцію обробник події scroll – повзунок скролла. Тобто коли користувач перемістить повзунок скролла, виконається функція, описана в даному методі. Далі перевіримо, якщо повзунок скролла знаходиться в самому низу сторінки і блокування скрипта не включена, то ми насамперед блокуємо скрипт: block = true;

Потім показуємо блок з класом load, використовуючи метод fadeIn(), зі швидкістю 500 мілісекунд і після завершення всіх анімаційних ефектів, виконається функція описана у другому параметрі методу fadeIn(). У цій функції ми першим ділом збільшуємо значення зміною page на одиницю, так як нам потрібно відобразити наступну сторінку. Потім звертаємося до методу ajax і передаємо йому наступні параметри:

url — шлях до фалу на сервері, до якого ми звертаємося, в даному випадку це index.php;

type – тип запиту, за допомогою якого ми передаємо дані, в нашому випадку це тип GET;

data – дані, що передаються на сервер. Передаємо параметр page – значення нової поточної сторінки і параметр move із значенням 1, необхідний для формування відповіді від сервера.

success – функція яка виконається після успішного виконання запиту. Дана функція приймає параметром page змінну html – відповідь від сервера, який ми з Вами сформуємо далі. Якщо ж відповідь від сервера прийшов і не дорівнює false, то в даному відповіді буде міститися html код наступної сторінки посторінкової навігації. Тому використовуючи метод appendTo(), ми додамо даний код в блок з ідентифікатором posts після його вмісту (як останній дочірній елемент). Далі миттєво приховаємо даний код (значення змінної html) і відразу ж покажемо за допомогою методу fadeIn(). Далі змінюємо вміст блоку з класом pager використовуючи метод text(), тобто поточне значення змінної page виводимо в даному блоці. Далі приховуємо блок з класом load і розблокуємо роботу скрипта, тобто змінну block записуємо значення false.

Дивіться так як при переміщенні скролла постійно спрацьовує обробник події scroll, роботу скрипта необхідно блокувати на час передачі даних на сервер, так як якщо користувач швидко переміщує скролл ми відправляємо дані на сервер, відразу ж повторно може спрацює обробник цієї події і так далі поки користувач не зупинить повзунок скролла. І вийде що ми на сервер будемо відправляти безліч запитів, а це створить серйозну навантаження, так і візуально буде виглядати погано, так як в одну мить з’явиться кілька сторінок підряд.

Для визначення того що повзунок скролла знаходиться в самому низу екрану, використовуємо наступні значення:

$(window).height() – висота вікна браузера;

$(document).height() – висота документа (іншими словами висота нашого сайту).

$(window).scrollTop() – значення повзунка скрола. Тобто висота, на яку піднімається контент сайту вгору, за межі видимої частини браузера при переміщенні повзунка скролла.

Значить, якщо $(window).height() + $(window).scrollTop() більше або дорівнює $(document).height() (висоті документа), отже можна стверджувати, повзунок знаходиться в самому низу браузера.

5. Формуємо відповідь від сервера

Коли ми звертаємося в файл index.php, використовуючи AJAX і передаємо параметр page зі значенням поточної сторінки, відразу ж спрацює перевірка:

if($_GET[‘page’]) {
$page = (int)$_GET[‘page’];
if(!$page) {
$page = 1;
}
}
else {
$page = 1;
}

І викликається функція get_posts() вже з новим значенням для поточної сторінки і в змінну $result буде збережений масив з новими статтями 10. Які необхідно відобразити на сайті. Значить ми повинні правильно сформувати відповідь від сервера і даний відповідь передати назад в javaScript. Який потрапить в змінну html, про яку ми з Вами говорив вище. Як Ви пам’ятаєте крім параметра page, ми в файл index.php передаємо параметр move, зі значенням 1. Значить в файл index.php після перевірки наявності осередку page в суперглобальном масиві GET, необхідно додати наступний код:

if($_GET[‘move’] == 1) {
foreach($result as $row) {
printf(«

%s

%s | %s


Нескінченний шутер з автоматичним завантаженням контенту
%s

%s

«,$row[‘title’], $row[‘author’], $row[‘date’], $row[‘img_src’], $row[‘discription’], $row[‘view’]);
}
exit();
}

Тобто перевіряємо чи є в суперглобальном масиві GET осередок move із значенням 1 і якщо так, то в циклі проходимо по масиву $result і як би виводимо його на екран. Але ми ж звертаємося до даного файлу віддалено, використовуючи AJAX тому на екран нічого не виведеться, а навпаки, все, що повинно було вывестись на екран, буде відповіддю від сервера, який потрапить в змінну html.

Після циклу викликаємо функцію exit(), що б відразу ж завершити роботу скрипта після відпрацювання циклу. Тепер можна перевіряти роботу скрипта в цілому.

Нескінченний шутер з автоматичним завантаженням контенту

Дивіться, при опусканні скролла в самий низ, з’являється спочатку блок з класом load а потім з’являється наступна сторінка, тобто далі опускаючи скролл вниз ми побачимо наступну сторінку.

Нескінченний шутер з автоматичним завантаженням контенту

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