В uCoz-е в шаблонах страниц с материалом различных модулей-каталогов можно использовать зарезервированный оператор <?$RELATED_ENTRIES$(…)?>, который выводит ссылки на схожие материалы. В круглых скобках указывается количество этих ссылок. Опытным путем удалось определить, что эта цифра не может быть больше 20. В принципе, этого вполне достаточно. Обычно на сайтах ставят 4-5 таких ссылок.
Однако у этого оператора есть маленький недостаток. Эти ссылки в конкретной статье при обновлении страницы ссылаются на одни и те же материалы в одной и той же последовательности. Один из моих клиентов обратил внимание на сей факт и попросил сделать так, чтобы они хотя бы менялись местами, "перемешивались". В этой статье попытаемся решить данную задачу.
HTML-код, генерируемый оператором <?$RELATED_ENTRIES$(…)?>, выглядит примерно следующим образом:
Code
<ul class="uRelatedEntries">
<li class="uRelatedEntry"><a href="http://site.ucoz.ru/publ/3-1-0-1">первая статья</a></li>
<li class="uRelatedEntry"><a href="http://site.ucoz.ru/publ/3-1-0-2">А это вторая статья</a></li>
<li class="uRelatedEntry"><a href="http://site.ucoz.ru/publ/3-1-0-4">Вышла третья статья</a></li>
<li class="uRelatedEntry"><a href="http://site.ucoz.ru/publ/3-1-0-5">Вышла 4-ая статья</a></li>
<li class="uRelatedEntry"><a href="http://site.ucoz.ru/publ/3-1-0-19">Вышла 5-ая статья</a></li>
<li class="uRelatedEntry"><a href="http://site.ucoz.ru/publ/3-1-0-20">Вышла 6-ая статья</a></li>
</ul>
Для оператора <?RELATED_ENTRIES$(…)?> в качестве аргумента лучше указать максимально допустимое значение: 20. При этом сам оператор <?RELATED_ENTRIES$(20)?> "обернем" в тег "div" с id=" uRelated", чтобы потом с помощью JavaScript можно было получить код элементов полученного списка. Фрагмент этого кода в шаблоне страницы с материалом будет выглядеть так:
Code
<div id="uRelated"><?RELATED_ENTRIES$(20)?></div>
В результате сгенерируемый uCoz-ом HTML-код будет выглядеть так:
Code
<div id="uRelated">
<ul class="uRelatedEntries">
<li class="uRelatedEntry"><a href="http://site.ucoz.ru/publ/3-1-0-1">первая статья</a></li>
<li class="uRelatedEntry"><a href="http://site.ucoz.ru/publ/3-1-0-2">А это вторая статья</a></li>
<li class="uRelatedEntry"><a href="http://site.ucoz.ru/publ/3-1-0-4">Вышла третья статья</a></li>
<li class="uRelatedEntry"><a href="http://site.ucoz.ru/publ/3-1-0-5">Вышла 4-ая статья</a></li>
<li class="uRelatedEntry"><a href="http://site.ucoz.ru/publ/3-1-0-19">Вышла 5-ая статья</a></li>
<li class="uRelatedEntry"><a href="http://site.ucoz.ru/publ/3-1-0-20">Вышла 6-ая статья</a></li>
</ul>
</div>
Для обращения к элементам данного списка используется JQuery-селектор:
Code
$('#uRelated ul.uRelatedEntries li.uRelatedEntry')
Элементы списка <ul class="uRelatedEntries"> можно представить в качестве массива строк, при условии, что сам список не пуст. Затем из этого массива "выдергивать" случайные элементы и добавлять их в новый массив, тем самым получая перемешанный список.
Исходя из этого, определим количество элементов в списке:
Code
<script type="text/javascript">
var countLi = $('#uRelated ul.uRelatedEntries li.uRelatedEntry').size();
</script>
Следующим шагом переменной MaxCountLi присваиваем максимальное количество элементов списка <ul class="uRelatedEntries">, которые надо будет вывести вместо элементов, генерируемых оператором <?RELATED_ENTRIES$(20)?>:
Code
<script type="text/javascript">
var countLi = $('#uRelated ul.uRelatedEntries li.uRelatedEntry').size();
var MaxCountLi = 4;// Указать свое значение
</script>
Если в списке <ul class="uRelatedEntries"> имеются элементы, то их HTML-коды представим в виде одномерного массива arrLiuRelatedEntry. Проверка наличия элементов в списке осуществляется с помощью условного оператора if(), условием которого будет выражение "countLi>0". Если это условие выполняется, то объявляем массив arrLiuRelatedEntry и добавляем в него элементы списка <ul class="uRelatedEntries">. При этом помним, что первый элемент массива имеет индекс "0", а последний "countLi-1". Ежели все же список элементов списка <ul class="uRelatedEntries"> пуст, выводится надпись "Похожих материалов нет". Для того, чтобы обратиться к определенному элементу списка <ul class="uRelatedEntries">, используется селектор :eq(index), где в качестве параметра index указывается номер элемента из всей выборки, и нумерация эта также начинается с нуля. То есть для того, чтобы выбрать первый элемент из списка, аргумент функции $() будет иметь вид "#uRelated ul.uRelatedEntries li.uRelatedEntry:eq(0)", а, например, третий — вид такой "#uRelated ul.uRelatedEntries li.uRelatedEntry:eq(2)". Перебор же всех элементов списка и передача их массиву arrLiuRelatedEntry производим в цикле for. За весь этот процесс отвечает фрагмент кода:
Code
<script type="text/javascript">
var countLi = $('#uRelated ul.uRelatedEntries li.uRelatedEntry').size();
var MaxCountLi = 4; // Указать свое значение
if (countLi>0) {
var arrLiuRelatedEntry = new Array();
for (var i=0; i<=countLi-1; i++) {
arrLiuRelatedEntry[i] = $('#uRelated ul.uRelatedEntries li.uRelatedEntry:eq('+i+')').html();
}
……………………………..
} else {
document.writeln('Похожих материалов нет');
}
</script>
Итак, благодаря данному фруагменту скрипта, в случае наличия похожих материалов получаем одномерный массив arrLiuRelatedEntry, элементы которого соответствуют элементам списка <ul class="uRelatedEntries">. Теперь в случайном порядке надо выбрать нужное количество элементов и заменить ими прежний список. Количество этих элементов указано в переменной MaxCountLi. Однако может возникнуть такая ситуация, что значение данной переменной будет превосходить количество элементов массива arrLiuRelatedEntry. В таком случае значение переменной MaxCountLi изменить, присвоив значение, равное количеству элементов массива arrLiuRelatedEntry. Поэтому после цикла for, в котором сформировался массив arrLiuRelatedEntry, осуществим данную проверку и, в случае необходимости, изменим значение переменной MaxCountLi:
Code
if (countLi<MaxCountLi) { MaxCountLi = countLi; }
С учетом всего выше сказанного общий код примет вид:
Code
<script type="text/javascript">
var countLi = $('#uRelated ul.uRelatedEntries li.uRelatedEntry').size();
var MaxCountLi = 4; // Указать свое значение
if (countLi>0) {
var arrLiuRelatedEntry = new Array();
for (var i=0; i<=countLi-1; i++) {
arrLiuRelatedEntry[i] = $('#uRelated ul.uRelatedEntries li.uRelatedEntry:eq('+i+')').html();
}
if (countLi<MaxCountLi) { MaxCountLi = countLi; }
……………………………..
} else {
document.writeln('Похожих материалов нет');
}
</script>
Осталось лишь "выдернуть" из массива arrLiuRelatedEntry, состоящего из элементов списка <ul class="uRelatedEntries">, в случайном порядке элементы в количестве, указанном в переменной MaxCountLi, и из них "составить" новый список. Формировать новый список будем в строковой переменной my_HTML, после чего ее значением заменим HTML-код списка <ul class="uRelatedEntries">.
Итак, объявим переменную my_HTML и присвоим ей значение пустой строки. Попутно объявим переменную i_random, присвоив ей нулевое значение:
Code
var i_random = 0;
var my_HTML = "";
Теперь с помощью цикла for нужное количество раз (определено переменной MaxCountLi) с помощью java-функции Math.random случайном образом по одному "выдергиваем" элементы из массива arrLiuRelatedEntry и из них составляем новый список похожих материалов. HTML-код нового списка будем формировать в текстовой переменной my_HTML, которой перед циклом была присвоена пустая строка. С каждым шагом цикла, после изменений переменной my_HTML, выбранному элементу массива arrLiuRelatedEntry присваивается значение элемента с индексом countLi-1 (последний элемент массива), а сама переменная countLi уменьшается на единицу. То есть мы на каждом шаге как бы укорачиваем на единицу наш массив, заменяя выбранный элемент последним элементом. Это позволит избежать повторений в новом списке. Код данного цикла:
Code
for (var i=1; i<=MaxCountLi; i++) {
i_random = Math.floor(Math.random() * countLi);
my_HTML = my_HTML + "<li class=\"uRelatedEntry\">" + arrLiuRelatedEntry[i_random] + "</li>";
if (i_random<countLi-1) { arrLiuRelatedEntry[i_random] = arrLiuRelatedEntry[countLi-1]; }
countLi--;
}
Для большей наглядности работу данного фрагмента демонстрирует следующая схема:
По завершении работы оператора for в список ul.uRelatedEntries записываем полученный новый код из строковой переменной my_HTML:
Code
$('#uRelated ul.uRelatedEntries').html(my_HTML);
Конечный код примет вид:
Code
<div id="uRelated"><?RELATED_ENTRIES$(20)?></div>
<script type="text/javascript">
// ******************************************************************
// Этот скрипт случайным образом отбирает определенное количество элементов
// из списка "#uRelated ul.uRelatedEntries li.uRelatedEntry",
// тем самым перемешивая их
// ******************************************************************
var countLi = $('#uRelated ul.uRelatedEntries li.uRelatedEntry').size();
var MaxCountLi = 4; // Указать свое значение
if (countLi>0) {
var arrLiuRelatedEntry = new Array();
for (var i=0; i<=countLi-1; i++) {
arrLiuRelatedEntry[i] = $('#uRelated ul.uRelatedEntries li.uRelatedEntry:eq('+i+')').html();
}
if (countLi<MaxCountLi) { MaxCountLi = countLi; }
var i_random = 0;
var my_HTML = "";
for (var i=1; i<=MaxCountLi; i++) {
i_random = Math.floor(Math.random() * countLi);
my_HTML = my_HTML + "<li class=\"uRelatedEntry\">" + arrLiuRelatedEntry[i_random] + "</li>";
if (i_random<countLi-1) { arrLiuRelatedEntry[i_random] = arrLiuRelatedEntry[countLi-1]; }
countLi--;
}
$('#uRelated ul.uRelatedEntries').html(my_HTML);
} else {
document.writeln('Похожих материалов нет');
}
</script>
Бурда Александр
|