http://blagtalkan.ru
http://oktpoisk.ru
http://mysorru.ru/
http://san-okt.ru/
http://pes6evolution.ru/
http://chasikigov.ru
http://serafimsovet.ru
http://filmsgov.ru
http://free-domen.ru
http://fithonda.ru/forums/index.php
http://avtogov.ru
http://www.1001bilet.com.ua/base/on-line/
http://pravilavoini.ru
http://school41ufa.ru
http://rusrav4.ru
Методы отображения | Книга AJAX
 

Самыми сложными методами объекта oMailbox являются мето.: нимающиеся выводом данных на экран. Методов отображения два: renderFolder() отображает содержимое папки, a renderMe отображает содержимое отдельного сообщения. Оба они выз тод updateUnreadCount(), отвечающий за обновление числа не ных сообщений рядом со ссылкой Inbox:
updatel/nreadCount: function (iCount) {
this.spnUnreadMail.innerHTML = iCount > 0 ? " (" + iCount + ")"
Этот метод принимает число непрочитанных сообщений в входного аргумента. Если оно больше нуля, оно записывается в мент spnLIn readMail, в противном случае туда записывается пустая стро¬ка. Теперь, когда у нас есть определение метода updateUnreadCountQ, можно приступить к рассмотрению более сложных методов. Метод renderFolder(), отображающий список сообщений в папке, полу¬чает этот список из свойства info. Но сначала он очищает форму выво¬да списка сообщений, чтобы потом было проще добавлять в него новую информацию о сообщениях:
renderFolder: function (){;-. var tblHain = this.tblMain;
while (tblMain.tBodies[0].hasChildNodes()) {
tblMain.tBodies[0].removeChild(tblMain.tBodies[0].fi rstChild);
// здесь находится остальной код.
В первой части этого фрагмента ссылка на таблицу tblMain сохраняет¬ся в локальной переменной. Затем производится удаление всех донер-них узлов из элемента (на который ссылается элемент масси¬ва tblMain. tBodies[0]). После удаления всех строк таблицы можно при¬ступать к ее новому заполнению.
В следующей части метод создает представление DOM фрагмента доку¬мента с сообщениями. Обратите внимание, что с целью упрощения изу¬чения метода мы показываем только новые строки программного кода:
renderFolder: function () {;
// удаление всех существующих строк
var oFragment = document.сreateDocumentFragment();
if (this.info.messages.length) { .
for (var i=0;i< this.info.messages.length; i++) {
var oMessage = this.info.messages[i];
var oNewTR = this.trTemplate.cloneNode(true);
oNewTR.id = "tr" + oMessage.id;
oNewTR.onclick = readMail; >
if (oMessage.unread) {
oNewTR.className = "new";
var colCells = oNewTR.getElementsByTagNameC'td");
var imgAction = colCells[0].childNodes[0];
imgAction.id = oMessage. id; ::
if (this.info.folder == TRASH) {
imgAction.onclick = restoreMail;
imgAction.src = sRestorelcon;
imgAction. title = sRestore;
} else {
imgAction.onclick = deleteMail; imgAction.src = sDeletelcon; imgAction.title = sDelete;

colCells[1].appendChild(
document.createTextNode(cleanupEmail(oMessage.from))); colCells[2].firstChild.style.visibility =
oMessage.hasAttachments ? "visible" : "hidden"; colCells[3].appendChild(
document.createTextNode(htmlEncode(oMessage.subject))): colCells[4].appendChild(document.createTextNode(oMessage. oFragment.appendChild(oNewTR);
} else {
var oNewTR = this.trNoMessages.cloneNode(true); oFragment.appendChild(oNewTR); ,
tblMain.tBodies[0].appendChild(oFragment); // здесь находится остальной код
В этом коде сначала создается фрагмент документа, в котором собираться дерево DOM. Далее проверяется число сообщений, есть хотя бы одно сообщение, значит, форма просмотра должна построена соответствующим образом, в противном случае по trNoMessages создается всего одна строка, которая затем доб к фрагменту документа. Но если сообщения есть, то создание и ление информации о них усложняется.
Обработка сообщений начинается с сохранения содержимого массива messages из свойства info в локальной переменной oMes тем по шаблону trTemplate создается новая строка, которая сох-ся в локальной переменной oNewTR (значение true входного ар~ метода cloneNode() гарантирует, что он вернет не ссылку на и~ элемент , а создаст его полноценный дубликат). Далее в а id вновь созданного элемента записывается числовой иденти^ сообщения, к которому добавляется префикс t г. Затем в качестве ботчика события onclick назначается метод readMail(), который описан позднее в разделе «Обработчики событий». Если сообще нее не было прочитано, то свойство oMessage.unread будет иметь ние true, и потому сообщению надо присвоить класс CSS new.1 щий шаг заключается в том, чтобы записать данные в отдельные ки таблицы.
Чтобы упростить обращение к ячейкам таблицы, с помощью метода getElementsByTagNameO извлекается коллекция ячеек (colCells). В первой ячейке каждой строки таблицы должен ся графический значок, изображающий операцию - либо у либо восстановление сообщения. Для удобства ссылка на фактический элемент сохраняется в переменной imgAction. После этого в ат¬рибут id элемента записывается идентификатор сообщения. Чтобы оп¬ределить, какое действие должно выполняться по щелчку на изобра¬жении, проверяется содержимое свойства info, folder. Если текущей папкой является Trash, то по щелчку на изображении сообщение долж¬но восстанавливаться; кроме того, соответствующим образом устанав¬ливаются свойства onclick, src и title. В противном случае по щелчку на изображении сообщение будет удаляться (и будут устанавливаться значения все тех же свойств). Оба обработчика события - restoreMail() и deleteMail() - представляют собой глобальные функции. Они будут описаны в разделе «Обработчики событий».
Во второй ячейке каждой строки отображается информация об отпра¬вителе. Для ее получения вспомогательной функции cleanupEmailO, описанной ранее в этой главе, передается значение свойства oMessage. form. Результат работы функции передается методу document.сreate-TextNode(). Он создает текстовый узел, который тут же добавляется в ячейку с помощью метода appendChild().
В третьей ячейке таблицы отображается значок, свидетельствующий о наличии вложений. Если свойство oMessage. hasAttachments содержит значение true, то свойство изображения visibility устанавливается равным visible, в противном случае - hidden. Для простоты операция присвоения выполняется с помощью составного оператора, а не услов¬ного оператора if.
Четвертая ячейка строки содержит тему сообщения, строка с которой передается в html Encode (), чтобы гарантировать, что все символы в стро¬ке с темой будут отображены корректно. Полученный текст нужен для создания текстового узла, который затем добавляется в ячейку тем же самым способом, каким добавлялась информация об отправителе в пер¬вую ячейку. В пятой ячейке строки отображается дата сообщения. По¬сле того как все ячейки строки будут заполнены, она добавляется к фрагменту документа и начинается следующая итерация цикла.
Независимо от того, сколько сообщений находится во фрагменте доку¬мента, он передается методу appendChildO тела таблицы, в результате чего все полученные строки отображаются на странице просмотра пап¬ки. Однако на этом работа метода не заканчивается. Необходимо ото¬бразить и еще кое-какую информацию.
Следует показать заголовок с названием папки, обновить на экране число непрочитанных сообщений и инициализировать элементы управления листанием страниц:
renderFolder function () {
// удаление всех существующих строк
// создание строк с информацией о сообщениях
if (this.hFolderTitle.innerHTML != aFolders[this.info.folder]){ this.hFolderTitle.innerHTML = aFolders[this.info.folder];

this.updateunreadCount(this.irifo.unreadCount);
, this.spnltems.style.visibility =.this.info.messages.length?
"visible" : "hidden";.. ....... . „
this, spnltems. innerHTML = this. info. firstMessage +-"-"
+ (this.info. firstMessage + this.info.messages.length - 1) +.-_ + this.info.messageCount;
if (this. info.pageCount >-1) { . *
this.imgNext.style.visibility = this.info.page < this.info.
"visible" : "hidden";
this. imgPrev.style.visibility = this.info.page > 1 ? •
"visible" ; "hidden";
} else { . • ;
this.imgNext.style.visibility = "hidden"; ' this.imgPrev.style.visibility = "hidden";

this.divFolder.style.display = "block"; this.divReadMail.style.display = "none"; this. divComposeMail. style, display = "none";.
Этот фрагмент кода прежде всего записывает в элемент hFolderT: звание папки, но только в том случае, если оно не соответствует нию, которое отображалось на экране раньше. Для этого сна™ вернется значение свойства innerHTML данного элемента, а потом чае необходимости в него записывается новое значение. Затем updateUnreadCount() передается количество непрочитанных с которое отображается рядом со ссылкой Inbox.
Если в папке имеется хотя бы одно сообщение, следует отоб мент spnltems. Этот элемент отображает счетчик страниц, «1-10 из 21». Таким образом, при наличии сообщений в свой мента visibility записывается значение visible, в противном hidden. Затем с помощью различных свойств объекта info соз. держимое элемента. Свойство firstMessage хранит номер пер щения на странице. Номер последнего сообщения можно в добавив количество сообщений к firstMessage и уменьшив п сумму на единицу. Общее количество сообщений в папке в свойстве messageCount.
Если все сообщения в папке не умещаются на одну страницу, мо вывести на экран значки imgNext и imgPrev, но по отдельн пользователь просматривает первую страницу, то не должен жаться значок imgPrev. Аналогичным образом, когда пользон" ходится на последней странице, не должен отображаться зна Next. С помощью свойства page, которое хранит номер текущей
цы, можно определить, должен ли отображаться тот или иной значок, я соответствующим образом установить значение свойства visibility. Разумеется, если все сообщения умещаются на одной странице, то ни один из этих значков не должен отображаться.
В заключение метод должен отобразить элемент divFolder и скрыть эле¬менты divReadMail и divComposeMail. Таким способом приложение выво¬дит список сообщений. Когда пользователь щелкает мышью по одному из сообщений, вызывается метод renderMessage(), переводящий прило¬жение в режим отображения содержимого выбранного сообщения.
Метод renderMessage() использует свойство message с той же целью, что метод renderFolder() - свойство info: для определения того, что следует отображать. Свойство message содержит всю информацию, необходи¬мую для вывода одиночного сообщения. Для начала метод выполняет перенос значений свойств объекта message в элементы страницы про¬смотра сообщения:
' renderMessage: function () {
this.hSubject.innerHTML = htmlEncode(this.message.subject); this.divMessageFrom.innerHTML = sFrom + "
+ htmlEncode(this.message.from); this.divMessageTo.innerHTML = sTo + " " + htmlEncode(this.message.to); this.divMessageCC.innerHTML = this.message.ee.length ?
sCC + " " + htmlEncode(this.message.ee) : ""; this.divMessageBCC.innerHTML = this.message.bcc.length ?
sBCC + "■■ + htmlEncode(this.message.bcc) : ""; this.divMessageDate.innerHTML = this.message.date; this.divMessageBody.innerHTML = this.message.message;
// здесь находится остальной код
this. updatel)nreadCount(this. message. unreadCount); . this.divFolder.style.display = "none";
this.divReadMail.style.display = "block"; . this.divComposeMail.style.display = "none";

Каждый из элементов отображает различные данные, получаемые из объекта message. Разумеется, большая часть этих данных обрабаты¬вается функцией html Encode (), чтобы обеспечить корректное отображе¬ние. Значения полей СС и ВСС записываются только в том случае, если они содержат какую-либо информацию, в противном случае в элемен¬ты divMessageCC и divMessageBCC записываются пустые строки, что фак¬тически приводит к их исчезновению с экрана.
Затем обновляется счетчик непрочитанных сообщений. Обновляется именно здесь потому, что все равно выполняется обращение к серверу, и едва ли можно найти серьезную причину, по которой следовало бы отказаться от получения такого незначительного объема информации. На заключительном этапе метод скрывает элементы divFolder и divCom¬poseMail и делает видимым элемент divReadMail. Однако на этом рассмотрение метода не заканчивается. В приведенном выше ф отсутствует код, который обслуживает вложения.
Обслуживание вложений по существу означает вывод списка жений, прикрепленных к сообщению в таком виде, чтобы п тель мог загрузить любое из них простым щелчком мыши. Эл Attachments, который определен в сценарии index, php, должен димым только в том случае, если к сообщению прикреплено одно вложение. Вот как строится эта часть отображения:
renderMessage: function () {
this.hSubject.innerHTML = htmlEncode(this.message.subject); this.divMessageFrom.innerHTML = sFrom + " "
+ htmlEncode(this.message.from); this.divMessageTo.innerHTML = sTo + " " + htmlEncode(this.message this.divMessageCC.innerHTML = this.message.ee.length ?
sCC + " " + htmlEncode(this.message.ee) : ""; this.divMessageBCC.innerHTML = this.message.bee.length ?
sBCC + " " + htmlEncode(this.message.bec) : ""; this.divMessageOate.innerHTML = this.message.date; this.divMessageBody.innerHTML = this.message.message;
if (this.message.hasAttachments) {
this.ulAttachments.style.display = "";
var oFragment = document.createOocumentFragmentO;
for (var i=0; i < this, message .'attachments, length; i++) { var oLI = document.createElement("li"); oLI.className = "attachment";
oLI.innerHTML = " (" + this.message.attachments[i].size + ")";
oFragment.appendChild(oLI);
this.ulAttachments.appendChild(oFragment);' this. HAttachments. style, display = ""; } else {
this.ulAttachments.style.display = "none"; this. HAttachments. style, display = "none"; this.ulAttachments.innerHTML = "";
this.updateUnreadCount(this.message.un readCount); this.divFolder.style.display = "none"; this.divReadMail.style.display = "block"; this.divComposeMail.style.display = "none";
},
Естественно, для начала с помощью свойства hasAttachments надо рить наличие вложений. Если вложения есть, то элемент ulAt
делается видимым, после чего производится обход в цикле всех вложе¬ний. На каждой итерации создается новый элемент <П />, и в его свой¬ство innerHTML записывается информация о вложении. После этого за¬полненный элемент добавляется к фрагменту документа. Когда будет создано полное представление DOM списка вложений, фрагмент доку¬мента добавится в элемент ulAttachments. После этого делается види¬мым элемент liAttachments, для чего в свойство display записывается пустая строка. Этот элемент представляет собой ссылку на список вло¬жений, расположенную в верхней части страницы.
Если сообщение не содержит вложений, то элементы ulAttachments и li¬Attachments делаются невидимыми, для чего в свойство display каждого из них записывается значение попе. Кроме того, очищается содержимое элемента ulAttachments, для этого в его свойство innerHTML записывается пустая строка. Это препятствует отображению списка вложений в сооб¬щениях, к которым они на самом деле не были присоединены.