четверг, мая 17, 2007

У меня теперь Ajax-powered блог

Я уже очень давно хотела сделать нормальную секцию последних комментариев. Потому что долгое время у меня на блоге были не последние комментарии, а последнии комментарии к последним постам. Делалось это через хак, предложенный Блоггером. Все это было криво и неудобно.
Сейчас Блоггер модернизируют чуть ли не каждый день. В частности, появился фид комментариев, которого раньше не было. Можно перейти на новый шаблон, который обладает большими возможностями, чем старый. Вроде как там и последние комментарии довольно просто подключить. Но переходить на новый шаблон мне было лень. Поэтому я решила как-нибудь встроить комментарии из фида на страницу.
Муж дал мне свою ajax'овую рыбу и на ее основе я написала код, который вытягивает из фида комментариев последние несколько и встраивает их в sidebar. В IE оно не работает, виноват не Ajax, виноват фид комментариев.
Так что у меня появился повод написать про Ajax. Муж отказывается писать посты про Ajax, он считает что и так уже слишком много про него написано, а он знает про Ajax недостаточно (скромничает то есть). Я так не считаю, так что я напишу что знаю.
HTML страничка представляет собой набор тегов, которые браузер как-то разбирает. По итогам разбора браузер формирует так называемое DOM-дерево. DOM расшифровывается как document object model. Это дерево можно просмотреть. В FireFox это здесь: Tools->DOM Inspector. Более того, в DOM-инспекторе вы можете его поменять.
Некоторое время назад, не помню когда, появилась интересная штука с трудно произносимым названием XMLHttpRequest и мне пришлось с ней поработать году эдак в 2003. Позже она станет известна как Ajax. Расшифровывается как "Asynchronous JavaScript and XML". Если объяснять по-человечески, то это означает, что, используя язык JavaScript, вы можете откуда-нибудь запросить, скажем, XML документ. Но и это еще не все. После получения данные из этого XML'а вы можете встроить в DOM дерево. Перестраивание DOM дерева выглядит красиво, как смена страницы без перезагрузки. В 2003 это смотрелось просто волшебно, ну и сейчас тоже ничего смотрится, хотя стало уже привычным.
Итак, мне нужно запросить фид комментарив и встроить его в DOM дерево. Код того, как это делается, можно посмотреть в исходнике основной странички блога.


function createRequest(){
try{
return new XMLHttpRequest(); //создаю объект запроса
} catch(Exception) {
return new ActiveXObject("Msxml2.XMLHTTP");
//если создание не удалось, то это IE(<7)
//здесь все происходит несколько иначе
}//try
}//createRequest

function getXML() {// функция получения XML
//тут лежит фид комментариев
var url = 'http://alenacpp.blogspot.com/feeds/comments/full';
var request = createRequest();

//создаю красивую картинку, которая будет веселить пользователя,
//пока XML не прогрузится
//в случае быстрого соединения ее не видно
//картинка опциональна, можно ее не добавлять вообще
var image = document.createElement('IMG');
image.src = "http://www.softwaremaniacs.org/Images/alenacpp/ajax-loader.gif";

request.onreadystatechange = function() {
//callback, который отрабатывает по ходу запроса
if (request.readyState != 4) //запрос окончен
return;
image.parentNode.removeChild(image); //убираю красивую картинку
if (request.status != 200) //запрос окончен без ошибок
return;
//полученный XML передаю в функцию парсинга
parseComments(request.responseXML);
}//onreadystatechange

//вставляю красивую картинку в DOM-дерево
var comments = document.getElementById('LastComments');
comments.parentNode.insertBefore(image, comments);

request.open('GET', url);
request.send('');
}//getXML

function parseComments(xml) {
var comments = document.getElementById('LastComments');
//это UL, к которому я буду добавлять LI элементы

var elements = xml.getElementsByTagName('entry');
//получаю элементы с нужным мне тегом
for (var i = 0; i < elements.length && i<6; i++) {
var li = comments.appendChild(document.createElement('LI')); //создаю LI

//создаю ссылку на комментарии
var links = elements[i].getElementsByTagName('link');
var link;
for (var j = 0; j < links.length; j++) {
var rel = links[j].getAttribute('rel');
var type = links[j].getAttribute('type');

if(rel == 'alternate' && type == 'text/html') {
link = links[j].getAttribute('href');
break;
}
}

//создаю дату
var date = elements[i].getElementsByTagName('published')[0].firstChild.nodeValue;
var date = date.replace(/(\d+)\-(\d+)\-(\d+).*/, '$3.$2.$1');

//заполняю LI
li.innerHTML = date+" :: "+'<a href="'+link+'" >'+elements[i].getElementsByTagName('author')[0].getElementsByTagName('name')[0].firstChild.nodeValue +'</a>';
}//for
}//parseComments

getXML(); //функция, инициирущая загрузку XML

Если вы смотрели код главной страницы блога, то заметили, что там все слегка не так. Это потому что подлые блоггеровцы поменяли возвращаемый content-type фида комментариев после того, как я добавила этот кусок ajax'а. Пришлось слегка извратиться, изврат не работает в IE. Поэтому мне все же, наверное, придется переходить на новый шаблон.

Ссылки по теме:
Бонус - генератор красивых картинок на загрузку

11 коммент.:

Unknown комментирует...

Для Firefox’а есть просто монстрорасширение — Firebug.

Есть и DOM-браузер, и просмотр исходника, и JavaScript консоль, и возможность вести логи, и исследование элементов, и правка их налету, и профайлер, и сетевой монитор…

odin комментирует...

не знаю как в старом, но в новом блоггере можно просто добавить фид на страницу, т.е. уже готовое решение

Анонимный комментирует...

Алена, пожалуйста, пощадите тех, кто читает Ваши посты в жж.
не пишите больше таких длинных строк, а то лента разъезжается.

Alena комментирует...

Алена, пожалуйста, пощадите тех, кто читает Ваши посты в жж.
не пишите больше таких длинных строк, а то лента разъезжается.


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

Unknown комментирует...

Что я вот не пойму пытаюсь добавить в шаблон код сгенерированный AdSense, но он удаляется
Blogger какимто образом чистит шаблон?
И где прочитать о различиях нового и старого

Alena комментирует...

Что я вот не пойму пытаюсь добавить в шаблон код сгенерированный AdSense, но он удаляется
Blogger какимто образом чистит шаблон?


Я добавляла в шаблон код AdSens'а, проблем не возникало. Может, забываешь шаблон сохранить?

И где прочитать о различиях нового и старого

Я читала про новый шаблон по ссылкам с Дашборда. Там есть Blogger Help и еще какие-то ссылки.

Анонимный комментирует...

Поэтому мне все же, наверное, придется переходить на новый шаблон

Если это плохо :), то можно попробовать такой способ:

var xmlDoc, xmlString = request.responseText;
if (document.implementation.createDocument) {
var parser = new DOMParser();
xmlDoc = parser.parseFromString(xmlString, "text/xml");
} else if (window.ActiveXObject){
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.loadXML(xmlString);
}
parseComments(xmlDoc);

Alena комментирует...

2Mash:
Спасибо большое, стало лучше :-)

Unknown комментирует...

Подскажите плиз как вы вставляете код в блог? какие средства используете? Просто сколько не мучился - не нашел как в блоггере красиво вставить пример html-кода.

Alena комментирует...

2beq:
Подскажите плиз как вы вставляете код в блог? какие средства используете? Просто сколько не мучился - не нашел как в блоггере красиво вставить пример html-кода.

Это не что-то стандартное блоггеровское, это highlight.js.

Unknown комментирует...

Сам пользую иной сервис и там напрягает постоянно смотреть код страницы и т.д... Спасибо за ссылку! буду прикручивать.