Как заставить AJAX читать между строк


Прислал: Дмитрий Шейко [ 27.11.2006 @ 12:34 ]
Раздел:: [ Веб-технологии ]


На страницах вашего сайта содержится множество специализированных терминов. Когда пользователь просматривает сайт у него могут возникать вопросы касательно этих терминов. Как сделать так, чтобы посетитель сайта по мере возникновения вопросов мог незамедлительно получать на них ответы? Раньше термины на страницах сайта оформлялись как ссылки и пользователь при желании мог кликать по ним и получать окно с контекстной подсказкой. Это подход достаточно неуклюжий, он отнимает у пользователя слишком много времени – на то чтобы кликнуть по ссылке, дождаться загрузки окна и затем закрыть окно. В эпоху AJAX мы можем быть ближе к пожеланиям пользователей. Мы можем сделать так чтобы уже при наведении мыши на термин незамедлительно появлялось сообщение с подсказкой и как только курсор мыши сдвинут с термина сообщение исчезало. Наличие этого сервиса не отразится на объеме страниц сайта. При запросе контекстной подсказки Java Script будет обращаться к внешнему словарю, получать содержание и отображать его.

Метод получения информации по неявному запросу может найти применение не только в словаре терминов. Обращали ли вы внимание на ссылки с двойным подчеркиванием в таких проектах как hotscripts.com и devarticles.com? Это контекстная реклама на основе движка IntelliTXT компании Vibrant Media. При наведении курсора мыши на подобную ссылку появляется окно с рекламным предложением на соответствующую тему. Эта технология уже получила название in-text advertising.

Все чаще и чаще подобный метод применяется и на новостных порталах. Посетители видят на главной странице портала лишь заголовки новостей. Однако при наведении курсора мыши на заголовок новости они получают ее краткое описание. Таким образом, на главной странице портала можно вместить куда как больше новостей. Посетить портала увидит заголовки и для того чтобы получить анонсы новостей, ему будет достаточно пробежаться курсором мыши по заголовкам.

Давайте теперь рассмотрим, каким образом реализуется контекстная подсказка с помощью AJAX. Программисту, освоившему этот метод, не составит труда заставить портал комментировать новости по запросу или же написать модуль in-text advertising.

Итак, очевидно нам следует позаботиться об окне сообщения, того самого, которое будет появляться каждый раз, когда посетитель наводит курсор на термин. Для того чтобы окно появлялось и исчезало мгновенно следует поместить его на скрытом DIV.

<div id="InstantMessage" class="instant_message">&nbsp;</div>

Для простоты эксперимента мы можем оформить его в стиле системных сообщений MS Windows.

<style>

.instant_message { padding: 5px; font-size: 12px; font-family: Arial; visibility: hidden; position: absolute; width: 240px; border: outset 2px #FFFFFF; background: #D4D0C8}

.instant_message a { width: 240px; padding: 2px 17px; color: black; text-decoration: none; cursor: default}

.instant_message a:hover {color: #ffffff; background: #0A246A}

</style>

Окно должно появиться в тот момент, когда посетитель навел курсор мыши на термин и исчезнуть когда курсор мыши будет за пределами термина. Причем, в тот самый момент окно должно содержать уже не пробел, а текст определения термина. Таким образом, мы должны поместить термины в тексте документа в inline тег, поддерживающий события onMouseOver и onMouseOut. Первому событию следует назначить функцию JavaScript, которая получит определение термина, поместит его в окно сообщения и покажет окно. Второму событию требуется назначить функцию, которая просто скроет окно сообщения.

<a onmouseover="getDefinition('термин', event);" onmouseout="hideMessage();">термин</a>

В параметре функции отображающей окно (getDefenition) сообщения надо указать термин. Этот термин будет использован для запроса текста определения посредством AJAX. Так как при показе окна нам потребуется его позиционировать под курсором мыши для поддержки Gecko-базированых браузеров в эту функцию также следует передать параметр event. Функция для сокрытия окна (hideMessage) не требует каких-либо параметров.

Теперь наша задача при вызове функции getDefinition заставить JavaScript позиционировать окно сообщения.

function adjustMessage(evt) {

MessageObj = document.getElementById('InstantMessage');

if (isThisMozilla) event=evt;

var rightedge = document.body.clientWidth-event.clientX;

var bottomedge = document.body.clientHeight-event.clientY;

if (rightedge < MessageObj.offsetWidth)

MessageObj.style.left = document.body.scrollLeft + event.clientX - MessageObj.offsetWidth;

else

MessageObj.style.left = document.body.scrollLeft + event.clientX;

if (bottomedge < MessageObj.offsetHeight)

MessageObj.style.top = document.body.scrollTop + event.clientY - MessageObj.offsetHeight;

else

MessageObj.style.top = document.body.scrollTop + event.clientY;

MessageObj.innerHTML = 'Loading...';

MessageObj.style.visibility = "visible";

}

Итак, мы имеем окно сообщения, рапортующее о загрузке данных. Теперь следует выполнить запрос к контролеру за определением термина. Вы можете написать собственные функции для обслуживания AJAX запросов (//en.wikipedia.org/wiki/AJAX). Но если вы только начинаете работать с AJAX, я могу порекомендовать вам готовую библиотеку от Yahoo (//developer.yahoo.com/yui/). В этом случае запросу будет выглядеть так:

function getDefinition(term,evt){

adjustMessage(evt);

var request = YAHOO.util.Connect.asyncRequest('POST', '//адрес_контроллера', callback, 'term='+term);

}

Раз мы запрашиваем контролер, очевидно, нам надлежит его написать. В общем случае это самая простая часть. Задача контроллера - вернуть описание термина переданного в POST. Каким бы языком программирования мы не пользовались при написании контроллера нам достаточно выполнить несколько простейших операций.

1. соединиться с базой данных

2. выполнить SQL запрос для получения определения термина

3. отобразить на консоль результат в следующем виде:

{

"errormsg" : "в случае ошибки ее код",

"content" : "текст определения"

}

Это структура данных, известная как JSON. Она воспринимается JavaScript в явном виде, как «родная». В случае использования AJAX-библиотеки YAHOO ответ контроллера обслуживается следующей конструкцией

var handleSuccess = function(o){

if(o.responseText !== undefined){

showMessage(o.responseText);

}

};

var handleFailure = function(o){

if(o.responseText !== undefined){

showMessage("Connection Error");

}

};

var callback =

{

success:handleSuccess,

failure:handleFailure,

argument:['foo','bar']

};

Нам осталось лишь описать функцию showMessage(), которая помещает принятый текст определения в окно сообщения

function showMessage(json) {

var respondStructure = eval( '(' + json + ')' );

MessageObj.innerHTML = respondStructure.content;

return false;

}

Как вы понимаете, для сокрытия окна сообщения потребуется лишь изменить атрибут объекта

function hideMessage(){

var MessageObj=document.getElementById('InstantMessage');

MessageObj.style.visibility="hidden";

}

Когда вы будете опробовать этот пример, едва ли вы встретитесь с проблемами под браузером MS IE, однако, в FireFox вы можете обнаружить мерцание окна сообщения. Это связано с тем, что FireFox своеобразно обслуживает события onMouseOver/onMouseOut. Впрочем, эту проблему можно решить путем расстановки флагов задержки в функциях обслуживания этих событий.

Скрипты приведенного здесь примера можно загрузить по адресу //www.phpclasses.org/browse/package/3505.html

Работу примеры можно увидеть на //www.cmsdevelopment.com/thesaurus/