Создание раздела "См. также"
Создание раздела "См. также"
При создании раздела "См. также" нам потребуется решить четыре задачи.
— Соотнести каждый пункт полосы навигации со списком связанных материалов соответствующей Web-страницы.
— Собственно создать раздел "См. также" после загрузки Web-страницы.
— Обеспечить загрузку Web-страницы при щелчке на гиперссылке этого раздела.
— Реализовать скрытие и раскрытие вложенных списков и выделение пункта полосы навигации при щелчке на гиперссылке раздела "См. также".
Начнем по порядку.
Откроем файл Web-сценария main.js и найдем в нем объявление функции generateInnerList, которая, как мы помним, создает за один раз один вложенный список в полосе навигации. Немного исправим ее код, чтобы он выглядел так, как показано в листинге 19.1.
Листинг 19.1
function generateInnerList(aDataBase, elInnerList) {
for (var i = 0; i < aDataBase.length; i++) {
var s = "<LI><CODE><A HREF="" + aDataBase[i].url + "">" +
aDataBase[i].name + "</A></CODE></LI>";
var htelItem = elInnerList.insertHtml("beforeEnd", s);
htelItem.related = aDataBase[i].related;
}
}
В главе 14 мы узнали о свойствах и методах, которые мы можем создать у любого экземпляра любого объекта и которые относятся только к данному экземпляру, не затрагивая другие, даже созданные на основе того же объекта. Так вот, для хранения списка материалов, связанных с какой-либо Web-страницей, мы создадим свойство экземпляра с именем related. Это свойство будет создано у экземпляра объекта HTMLElement, представляющего пункт вложенного списка, который соответствует данной Web-странице. Метод insertHtml (см. листинг 19.1) как раз возвращает экземпляр объекта HTMLElement, что нам на руку.
Первую задачу — соотношение пункта полосы навигации со списком связанных материалов — мы решили.
Найдем объявление функции prepareSamples, которая подготавливает текст примеров и, что важно для нас, выполняется после загрузки фрагмента содержимого. Добавим в конец тела функции, передаваемой в качестве параметра методу each, такое выражение:
generateRelated();
Это вызов функции generateRelated, которая и создаст раздел "См. также" и которую мы сейчас объявим.
Не будем откладывать дело в долгий ящик. Листинг 19.2 содержит объявление функции generateRelated.
Листинг 19.2
function generateRelated() {
var s = "";
var oRelated = elLastItem.dom.related;
if (oRelated) {
for (var i = 0; i < oRelated.length; i++) {
if (s!= "")
s += ", ";
s += "<CODE><A HREF="" + oRelated[i].url + "">" +
oRelated[i].name + "</A></CODE>";
}
var htelRelated = Ext.get("cmain"). insertHtml("beforeEnd", "<P>См. также: " + s + "</P>"); Ext.fly(htelRelated). select("A"). on("click", function(e, t) {
var href = Ext.fly(this). getAttribute("href");
var elA = Ext.get("navbar"). child("A[href=" + href + "]");
var elItem = elA.parent("LI");
loadFragment(elItem, e);
});
}
Рассмотрим приведенный код построчно.
Объявляем переменную s, в которой будет храниться HTML-код, формирующий раздел "См. также" в виде строки:
var s = "";
Первое, что нам нужно, — получить список материалов, связанных с загруженной в данный момент Web-страницей (точнее, фрагментом содержимого). Как его получить? Вспомним, что еще в главе 17 мы объявили переменную elLastItem. Она хранит пункт полосы навигации, на котором посетитель щелкнул мышью и который как раз и соответствует загруженному в данный момент фрагменту содержимого. Вот и решение:
var oRelated = elLastItem.dom.related;
Значение переменной elLastItem — это экземпляр объекта Element. Соответствующий ему экземпляр объекта HTMLElement мы можем получить через свойство dom. А полученный экземпляр объекта HTMLElement, в свою очередь, содержит свойство related, которое и хранит массив конфигураторов, представляющих Web-страницы со связанными материалами; мы сами создали это свойство при формировании пунктов вложенных списков (исправленная функция generateInnerList).
Проверяем, присутствует ли это свойство в экземпляре объекта HTMLElement, т. е. существует ли у данной Web-страницы список связанных материалов:
if (oRelated) {
Если существует, запускаем цикл со счетчиком, который обработает все элементы этого массива:
for (var i = 0; i < oRelated.length; i++) {
Фрагменты HTML-кода, формирующие отдельные гиперссылки раздела "См.
также", мы будем добавлять в строку, хранящуюся в переменной s:
if (s!= "")
s += ", ";
Эти гиперссылки следует разделить запятыми, что и выполняет приведенное выражение. Оно проверяет, есть ли в переменной s непустая строка, т. е. сформирована ли в ней хотя бы одна гиперссылка, и, если это так, добавляет к ней запятую — разделитель гиперссылок.
Формируем HTML-код, создающий гиперссылку на очередную Web-страницу из списка связанных материалов, и добавляем его к значению переменной s:
s += "<CODE><A HREF="" + oRelated[i].url + "">" + oRelated[i].name + "</A></CODE>";
}
На этом тело цикла завершается.
Далее создаем на основе сформированного HTML-кода абзац, который и станет разделом "См. также". Добавляем его в самый конец контейнера cmain (перед его закрывающим тегом):
var htelRelated = Ext.get("cmain"). insertHtml("beforeEnd", "<P>См. также: " + s + "</P>");
Выбираем из сформированного в предыдущем выражении абзаца все гиперссылки и привязываем к ним функцию — обработчик события click, которую там же и объявляем:
Ext.fly(htelRelated). select("A"). on("click", function(e, t) {
Первым делом эта функция получит значение атрибута HREF — интернет-адрес — гиперссылки, на которой щелкнули мышью:
var href = Ext.fly(this). getAttribute("href");
Далее она ищет в списке navbar гиперссылку с тем же интернет-адресом:
var elA = Ext.get("navbar"). child("A[href=" + href + "]");
Пункты нашей полосы навигации не содержат повторяющихся интернет-адресов, поэтому такой прием будет работать.
Найдя такую гиперссылку, она получает ее родителя — сам пункт:
var elItem = elA.parent("LI");
который, вместе с экземпляром объекта EventObject, представляющим возникшее событие, "скармливает" объявленной нами в главе 17 функции loadFragment. Последняя выполнит загрузку соответствующего фрагмента содержимого и выделит соответствующий пункт полосы навигации:
loadFragment(elItem, e);
});
}
На этом выполнение функции generateRelated заканчивается.
Теперь отыщем код, объявляющий функцию cleanupSamples. Она, как мы помним, удаляет обработчики событий у текста примеров перед загрузкой другого фрагмента содержимого. Это нужно, чтобы не засорять внутренние структуры данных библиотеки Ext Core сведениями о привязке обработчиков событий к уже не существующим элементам Web-страницы.
Нам нужно дополнить этот код, чтобы он также удалял обработчики событий у гиперссылок раздела "См. также". Сделаем проще — будем выбирать все гиперссылки в контейнере cmain и удалять у них обработчики событий.
Листинг 19.3 содержит дополненное объявление функции cleanupSamples.
Листинг 19.3
function cleanupSamples() {
var ceSamples = Ext.select(".sample");
ceSamples.each(function(el, cl, ind){ var elH6 = el.child(":first"); elH6.removeAllListeners();
});
var ceA = Ext.get("cmain"). select("A");
ceA.removeAllListeners();
}
Так, вторая и третья задачи решены. Мы сформировали раздел "См. также" и реализовали загрузку Web-страницы при щелчке на гиперссылке этого раздела.
Теперь представим себе такую ситуацию. Посетитель щелкает на каком-либо пункте полосы навигации, Web-обозреватель выводит соответствующую Web-страницу и формирует на ней раздел "См. также". Этот раздел содержит несколько гиперссылок, указывающих на Web-страницы с описаниями тегов HTML (первый раздел — "HTML"), и несколько гиперссылок, указывающих на Web-страницы с описаниями атрибутов стиля CSS (второй раздел — "CSS"). Предположим, что загруженная в данный момент Web-страница также содержит описание тега HTML (принадлежит к первому разделу); значит, первый, представляющий Web-страницы из первого раздела, вложенный список в полосе навигации открыт, остальные — скрыты.
В этот момент посетитель щелкает на гиперссылке раздела "См. также", ведущей на Web-страницу с описанием атрибута стиля CSS (принадлежащей второму разделу), и Web-страница успешно загружается. По идее, второй вложенный список (который представляет все Web-страницы второго раздела) в полосе навигации должен быть открыт, а первый, открытый ранее, — скрыт. Ничего подобного! Первый вложенный список так и останется открытым.
Дело в том, что, создавая в главе 17 Web-сценарий, управляющий скрытием и раскрытием вложенных списков в полосе навигации и выделением ее пунктов, мы полагали, что щелкать на пунктах полосы навигации будет человек. А он в принципе не может щелкнуть на пункте, находящемся в скрытом списке, — ведь скрытый список вообще не присутствует на Web-странице. Поэтому мы не реализовали в функции loadFragment возможность открытия вложенного списка, на пункте которого щелкнул посетитель, — это было просто незачем.
Сейчас же мы написали функцию generateRelated, которая создает раздел "См. также" с набором гиперссылок и привязывает к ним обработчик события click. Этот обработчик находит в полосе навигации пункт, который имеет гиперссылку с тем же интернет-адресом, и, если можно так сказать, программно "щелкает" на нем. А он ведь может "щелкнуть" и на пункте скрытого списка!
Вывод: нам потребуется дополнить объявление функции loadFragment так, чтобы она открывала вложенный список, на пункте которого "щелкнули", если, конечно, он еще не открыт. Найдем это объявление и отыщем в нем фрагмент кода, приведенный в листинге 19.4.
Листинг 19.4
.
} else {
if ((elLastItem) && (elLastItem.dom!= elLI.dom))
elLastItem.removeClass("selected");
elLI.addClass("selected");
elLastItem = elLI;
}
Этот код управляет выделением пункта вложенного списка, на котором щелкнули мышью или "щелкнули" программно. Дополним его так, как показано в листинге 19.5.
Листинг 19.5
} else {
var elInnerList = elLI.parent("UL");
if ((elLastInnerList) && (elLastInnerList.dom!= elInnerList.dom))
elLastInnerList.setDisplayed(false); elInnerList.setDisplayed(true); elLastInnerList = elInnerList;
if ((elLastItem) && (elLastItem.dom!= elLI.dom))
elLastItem.removeClass("selected");
elLI.addClass("selected");
elLastItem = elLI;
}
Добавленные нами выражения находят вложенный список, в котором присутствует данный пункт, проверяют, открыт ли он в текущий момент, и, если не открыт, открывают, скрывая при этом ранее открытый список.
Вот решена и четвертая задача… Уф-ф-ф!
Сохраним все исправленные файлы и проверим готовую Web-страницу index.htm в действии. Откроем Web-обозреватель, наберем в поле ввода интернет-адрес http://localhost, пощелкаем на пунктах полосы навигации и гиперссылках раздела "См. также" и посмотрим на сменяющие друг друга Web-страницы и скрывающиеся и открывающиеся вложенные списки. Красота!
Здесь мы реализовали раздел "См. также" в виде абзаца с гиперссылками. Также его можно выполнить в виде списка или таблицы. Можно даже сделать раздел скрывающимся и раскрывающимся в ответ на щелчок мышью. Так, кстати, часто и поступают. Вы тоже можете так сделать; пусть это будет вашим домашним заданием.
Что дальше?
В этой главе мы познакомились с принципом семантической разметки данных и применили ее к нашей базе данных средствами JavaScript. В результате мы смогли создать на Web-страницах нашего Web-сайта раздел "См. также", содержащий гиперссылки на Web-страницы со связанными данными.
Помнится, мы планировали реализовать на Web-сайте еще и поиск материалов по введенному посетителем слову или фрагменту слова. Далее мы им займемся. И начнем с элементов управления, с помощью которых реализуется ввод данных посетителем.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
Создание раздела "См. также"
Создание раздела "См. также" При создании раздела "См. также" нам потребуется решить четыре задачи.— Соотнести каждый пункт полосы навигации со списком связанных материалов соответствующей Web-страницы.— Собственно создать раздел "См. также" после загрузки
8.1.5 Планирование на основе справедливого раздела
8.1.5 Планирование на основе справедливого раздела Вышеописанный алгоритм планирования не видит никакой разницы между пользователями различных классов (категорий). Другими словами, невозможно выделить определенной совокупности процессов, например, половину сеанса
16.2. Структура дискового раздела в ext2fs
16.2. Структура дискового раздела в ext2fs Производители жестких дисков обычно поставляют свои изделия отформатированными на низком уровне. Насколько я знаю, это означает, что все дисковое пространство с помощью специальных меток разбито на "сектора", размером 512 байт. Такой
4.10. Создание раздела (файла) подкачки
4.10. Создание раздела (файла) подкачки Рано или поздно при работе с Linux вам станет недостаточно оперативной памяти: потребности растут, а возможности (оперативная память) остаются прежними. В этом случае нужно купить дополнительные 128...256 Мб, тем более, что цены на память
Параметры раздела идентификатора
Параметры раздела идентификатора Раздел идентификатора может содержать следующие параметры.? EditFlags — данный параметр DWORD-типа определяет различные ограничения на модификацию параметров данного расширения при помощи вкладки Типы файлов диалога Свойства папки.
Подразделы корневого раздела
Подразделы корневого раздела Как видите, сведения о расширениях файлов хранятся в реестре в виде упорядоченных данных (чего, к сожалению, нельзя сказать о других корневых разделах реестра, структура которых если и прослеживается, то только в некоторых местах).Но не
Параметры раздела ActiveX-объекта
Параметры раздела ActiveX-объекта Раздел CLSID включает в себя список вложенных подразделов, каждый из которых назван на основе CLSID-номера ActiveX-объекта, который он описывает, и хранит сведения только об этом ActiveX-объекте. Подраздел ActiveX-объекта может содержать следующие
Другие разделы корневого раздела
Другие разделы корневого раздела Уже была рассмотрена большая часть содержимого корневого раздела реестра HKEY_CLASSES_ROOT — разделы расширения, идентификатора и раздел CLSID, но, кроме них, корневой раздел включает в себя еще несколько разделов, которые стоит описать. Некоторые
2.1.18. Итоги первого раздела
2.1.18. Итоги первого раздела Мы рассмотрели основные принципы работы со стандартными сокетами. Хотя многое осталось за кадром, того, что здесь было написано, достаточно, чтобы начать создавать разнообразные приложения с использованием сокетов. Для самостоятельного
3.2. Типы раздела
3.2. Типы раздела Этот раздел обсуждает типы выделения разделов, которые доступны в MySQL 5.1. Они включают:– RANGE partitioning : назначает строки разделам, основанным на значениях столбца, попадающих внутрь заданного диапазона.– LIST partitioning: подобно выделению разделов диапазоном, за
Термины, которые вам потребуются при изучении этого раздела
Термины, которые вам потребуются при изучении этого раздела Вирус – программа, которая способна размножаться, прикрепляя себя к безобидным программам или документам. Вирус может повредить или полностью уничтожить все файлы и данные, а также повредить или даже
Термины, которые вам потребуются при изучении данного раздела
Термины, которые вам потребуются при изучении данного раздела Аська (ICQ – от англ. «I seek you», «я ищу тебя») – служба мгновенного обмена сообщениями.Блог (от англ. «web log», в переводе «сетевой журнал или дневник событий») – сайт, на котором можно разместить свой электронный
2.5.4. Выбор раздела жесткого диска
2.5.4. Выбор раздела жесткого диска Следующий шаг — выбор раздела, в который нужно установить Windows 7. Мне было проще — я устанавливал Windows 7 на неразмеченный жесткий диск, поэтому все, что мне пришлось сделать — это выбрать неразмеченную область (рис. 2.9) и нажать кнопку
5.1. Создание нового раздела
5.1. Создание нового раздела Как уже было сказано, в реестре имеется пять корневых разделов. Вы не можете создать еще один корневой раздел, однако можете создать раздел в любом из имеющихся корневых разделов (он будет представлять собой раздел первого уровня по отношению к