четверг, мая 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 комментирует...

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