Блог студии веб-дизайна «Make a Site» Дизайн, верстка, программирование, наполнение и раскрутка сайтов.

Постраничная навигация: обычная и при помощи стрелок на клавиатуре

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

Постраничная навигация: обычная и при помощи стрелок на клавиатуре
Содержание статьи

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

Несколько слов о постраничной навигации

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

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

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

Реализация постраничной навигации на php

Итак, приступим к делу. Сначала нам нужно найти тот запрос, который достает наши с вами записи из базы данных. Допустим, мы выводим на одной из страниц нашего сайта список новостей и их стало больше 50, поэтому мы решили разбить наши записи на страницы и показывать ссылки на эти страницы под списком новостей.

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

Предположим запрос у вас был такой:

$rs = mysql_query("SELECT * FROM `news` ORDER by `ID` DESC");

Тут все просто и понятно, вы просто брали все записи из таблицы news. Для того, чтобы брать записи порционно, в зависимости от текущей страницы, нам нужно немного доработать этот запрос:

$rs = mysql_query("SELECT * FROM `news` ORDER by `ID` DESC LIMIT ".(intval($_GET['p']) ? ((intval($_GET['p']) - 1) * 50) : '0').", 50");

Что мы сделали? Мы просто добавили LIMIT 0,50 и написали условие, при котором лимит будет передвигаться в зависимости от атрибута $_GET['p'] в адресе страницы, т.е. www.domain.com/news/ - первая страница (по умолчанию), www.domain.com/news/?p=2 - вторая страница, www.domain.com/news/?p=3 - третья и так далее. Значит на первой странице лимит будет 0,50, на второй - 50,50, на третьей - 100,50 и так далее.

Функция постраничной навигации php

А теперь давайте напишем самое важное - мозг нашей навигации - главную функцию pageNavigation:

function pageNavigation($itemsPerOnePage, $query) {
	$rs = mysql_query($query);
	$row = mysql_fetch_assoc($rs);
	$items = $row['COUNT'];
	if($items > $itemsPerOnePage) {
		$currentPage = (intval($_GET['p']) ? intval($_GET['p']) : '1');
		$url = parse_url("http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
		$url['query'] = str_replace(array("&p=".$_GET['p'], "p=".$_GET['p']), "", $url['query']);
		$totalPages = ceil($items / $itemsPerOnePage);
	}
	// 5 страниц назад и 5 вперед от текущей
	$plusMinus = 5;
	for($p=$currentPage-$plusMinus;$p<=$currentPage+$plusMinus;$p++) {
		if($p > 0 && $p <= $totalPages) {
			if($p == $currentPage) {
				$result .= '<li class="current">'.$p.'</li>';
			}
			else {
				$result .= '<li><a href="'.($p > 1 ? $url['path'].($url['query'] ? '?'.$url['query'].'&' : '?').'p='.$p : $url['path'].($url['query'] ? '?'.$url['query'] : '')).'">'.$p.'</a></li>';
			}
		}
	}
	if($totalPages > 1 && $result) {
		return '<div class="page-navigator">Страницы:<ul>'.($currentPage > 1 ? '<li class="ctrl-button prev"><a href="'.($currentPage > 2 ? $url['path'].($url['query'] ? '?'.$url['query'].'&' : '?').'p='.($currentPage-1) : $url['path'].($url['query'] ? '?'.$url['query'] : '')).'" id="PrevLink">предыдущая</a></li>' : '').$result.($currentPage < $totalPages ? '<li class="ctrl-button next"><a href="'.$url['path'].($url['query'] ? '?'.$url['query'].'&' : '?').'p='.($currentPage+1).'" id="NextLink">следующая</a></li>' : '').'</ul></div>';
	}
}

Наша функция имеет два атрибута - $itemsPerOnePage - сколько мы хотим записей на каждой странице (в рамках данной статьи мы рассматриваем 50), $query - упрощенный запрос, который выводит записи на странице. Если с количеством записей все понятно, то насчет упрощенного запроса стоит пояснить подробней.

Напомним, что основной запрос у нас был следующим:

$rs = mysql_query("SELECT * FROM `news` ORDER by `ID` DESC");

Значит упрощенный будет выглядеть следующим образом:

$rs = mysql_query("SELECT COUNT(`ID`) AS `COUNT` FROM `news`");

Все! Больше ничего не требуется. Мы убрали звездочку, дабы не нагружать сервер, а то вдруг у нас уже 100.000 новостей в базе. Вместо этого мы ищем сумму записей в таблице news и присваеваем это значение альясу с произвольным именем - COUNT. Также мы убрали сортировку по ID, т.к. в данном случае нам все равно в какой последовательности считаются записи, все что нам нужно от этого запроса - это просто узнать количество записей в таблице news.

Стоит добавить, что функцию mysql_num_rows не стоит использовать вообще, т.к. она довольно ресурсоемка и работает намного медленней, чем COUNT(`ID`).

Данная функция универсальна и если у вас есть какие-то дополнительные параметры в GET-запросе, это никак не повлияет на работу функции, также функция не выдает ссылку вида ?p=1, она игнорирует параметр, если ссылка идет на первую страницу, то понятное дело, что p = 1 и она этого не показывает, дабы не было двух копий одной и той же страницы www.domain.com/news/ и www.domain.com/news/?p=1

В итоге вызов функции на странице новостей будет выглядеть так:

echo pageNavigation(50, "SELECT COUNT(`ID`) AS `COUNT` FROM `news`");

Вот и все! А теперь давайте перейдем к обещанному бонусу - добавим к нашей навигации управление с клавиатуры...

Постраничная навигация при помощи стрелок на клавиатуре и клавиши Ctrl

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

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

Итак давайте перейдем к делу и для начала займемся разметкой.

<div class="ctrl-button prev">
	<a href="/prev" id="PrevLink">назад</a>
</div>
<div class="ctrl-button next">
	<a href="/next" id="NextLink">вперед</a>
</div>

Просто добавьте идентификаторы к вашим ссылкам как показано на примере. И поместите их в контейнеры с соответствующими классами.

Теперь сама функция, которая будет реагировать на комбинации Ctrl + ← и Ctrl + →

document.onkeydown = NavigateThrough;
function NavigateThrough (event)
{
	if (event.ctrlKey)
	{
		var link = null;
		var href = null;
		switch (event.keyCode ? event.keyCode : event.which ? event.which : null)
		{
			case 0x25:
				link = document.getElementById ('PrevLink');
				break;
			case 0x27:
				link = document.getElementById ('NextLink');
				break;
		}
		if (link && link.href) document.location = link.href;
	}
}

Также можно добавить следующий код, чтобы при "ручном" клике на изображение клавиш происходил переход на нужную страницу:

$(document).ready(function() {
	$(".ctrl-button.prev, .ctrl-button.next").click(function(){
		window.location=$(this).find("a").attr("href"); return false;
	});
});

Ну и остался последний момент - стили:

/*=====================================*/
.page-navigator {
	margin: 50px 0 0 0;
}
.page-navigator ul {
	margin: 10px 0 0 0;
	padding: 0;
}
.page-navigator li {
	display: inline-block;
	padding: 5px;
	line-height: 19px;
}
.ctrl-button {
	height: 19px;
	line-height: 19px;
	cursor: pointer;
}
.ctrl-button.prev {
	background: url(/i/ctrl-buttons.png) 0 0 no-repeat;
	padding: 0 0 0 52px;
}
.ctrl-button.prev:hover {
	background-position: 0 -19px;
}
.ctrl-button.next {
	background: url(/i/ctrl-buttons.png) 100% -38px no-repeat;
	padding: 0 52px 0 0;
}
.ctrl-button.next:hover {
	background-position: 100% -57px;
}
/*=====================================*/

А вот и само изображение стрелок:

Итак, теперь собираем все это вместе и получаем наглядный пример работы функции.

А вот и пример работы собранной нами функции постраничной навигации + бонус: навигация при помощи стрелок на клавиатуре и зажатой клавиши Ctrl.

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

открыть в новой вкладке



Предыдущая статья:
Ускорение индексации сайта на WordPress. Пинг сервера и службы слежения за обновлениями

Читайте также:
Раскрутить или не раскрутить? Нужно ли раскручивать сайт?

Возможно, вам это интересно:



Блог студии веб-дизайна «Make a Site».
Дизайн, верстка, программирование, наполнение и раскрутка сайтов.

Текущий проект: «Stream Booster» — раскрутка Twitch и YouTube каналов

Студия веб-дизайна «Make a site»