Внимание! Данная статья скорее всего устарела и описываемое ниже имеет больше академичсекий интерес.
Для начала. Все началось с того, что, заинтересовавшись AJAX, мне захотелось попробовать уйти от его основного недостатка: невозможности сохранять результаты в нормальном виде на локальном диске. Великий и могучий Интернет подарил замечательную статью Красносельского Константина Константиновича про AJAX (ссылку см. в конце заметки).
В статье, кроме всего прочего, речь шла о возможности отказа от классов JavaScript (в частности xHTTPRequest) в пользу использования IFRAME для реализации динамической погрузки содержимого без перезагрузки страницы. Разумеется, не обошлось и без JavaScript:) Я немного «довел под себя» предлагаемое решение, оставив неизменной идею.
Но обо всем по-порядку.
Постановка задачи:
Необходимо сформировать на сервере при помощи php код html, который разместить в отдельном элементе (например, в <div>) страницы.
Решение (в несколько действий):
Действие 1:
В основной странице (т.е. там, где мы предполагаем делать динамические AJAX вставки) определяем элемент-контейнер. Для наглядности поместим в него кнопку, которая будет инициировать заполнение элемента:
<div id=’myelm’>
<input type=”button” value=”Load”>
</div>
.
Действие 2:
В основном файле страницы определяем невидимый iframe, который будет выступать контейнером:
<iframe onLoad="javascript:ol();" src="" name="sframe" id="sframe" width="0" height="0" scrolling="no" frameborder="0" style="display: none"></iframe>
Я (на всякий случай) определяю этот iframe в самом конце страницы. Про обработчик onLoad и для чего он нужен будет подробнее описано чуть ниже.
Действие 3:
Определяем обработчик нажатия на кнопку и обработчик загрузки невидимого фрейма
<script language="javascript">
function btn_go()
{
window.frames.sframe.location.href = 'include.html';
}
function ol()
{
if (window.frames.sframe.document.body.innerHTML!='')
{window.document.getElementById('myelm').innerHTML=window.frames.sframe.document.body.innerHTML;}
}
</script>
Естественно, что файл include.html – это исключительно демонстрация. Никто не мешает нам написать, например, следующее:
window.frames.sframe.location.href = ‘srv_return.php?s=1&d=2&f=3&res=221?=664ub&etc=11’;
то есть, вызвать php скрипт, результаты работы которого будут отображены в контейнере div
Подробнее стоит остановиться на функции ol(). Ее появление обусловлено тем, что IE (я тестировал на версии 6) не умеет дожидаться загрузки документа. То есть, если бы я определил функцию btn_go() так:
function btn_go()
{
window.frames.sframe.location.href = 'include.html';
window.document.getElementById('myelm').innerHTML=window.frames.sframe.document.body.innerHTML;
}
то при использовании IE контейнер бы просто обнулялся (сценарий уже выполнен, а документ еще не успел загрузиться – можете проверить)
Действие 4:
Подправляем код кнопки в контейнере, связывая обработчик, который разработан на предыдущем шаге, с кнопкой, которая определена в действии 1; одновременно для наглядности «раскрасим» div:
<div id=’myelm’ style=”border: 1px solid blue; background-color: gray;”>
<input type=”button” value=”Load” onClick=”javascript:btn_go();”>
</div>
Действие 5:
Opera (у меня версии 9) «не понимает» конструкции about:blank (пустая страница) и заполняет невидимый фрейм чем-то по своему усмотрению. В итоге, следует предусмотреть «обнуление» фрейма при создании основного документа:
<body onLoad="javascript:window.frames.sframe.document.body.innerHTML='';">
Собственно говоря, все.
Для наглядности приведу демо-примеры полностью
1. Файл client_example.html
<html>
<head>
<title>Example</title>
<script language="javascript">
function btn_go()
{
window.frames.sframe.location.href = 'include.html';
}
function ol()
{
if (window.frames.sframe.document.body.innerHTML!='')
{window.document.getElementById('myelm').innerHTML=window.frames.sframe.document.body.innerHTML;}
}
</script>
</head>
<body onLoad="javascript:window.frames.sframe.document.body.innerHTML='';">
<div id='myelm' style="border: 1px solid blue; background-color: gray;">
<input type="button" value="Load" onClick="javascript:btn_go();">
</div>
<iframe onLoad="javascript:ol();" src="" name="sframe" id="sframe" width="0" height="0" scrolling="no" frameborder="0" style="display: none"></iframe>
</body>
</html>
2. Файл include.html
<span style="">Hello!<br>
This is AJAX script.</span>
(обратите внимание, что в этом файле содержится (а потенциально – генерируется) только тот текст, который должен быть встроен в контейнер, без тегов типа <html> и т.д.)
Таким образом можно, например, организовать на сайте поиск, показ результатов голосования и т.д. без перезагрузки всей страницы.
PS. Возникает вопрос - а почему бы, вместо того, чтобы изображать все описанное выше, не использовать просто IFRAME? Вроде проще и надежнее. Это, безусловно, так. Но! Если мы разрабатываем сложную динамическую страницу с элементами div, которые могут перекрыть требуемый нам элемент, то в случае с IFRAME и IE IRFAME будет "просвечивать" сквозь div - т.к. с точки зрения IE, IFRAME (как оконный элемент управления) имеет бесконечно большой z-index... Кстати, в Opera (версии 9) был обнаружен схожий глюк.
Приведенное же выше решение указанного недостатка не имеет.
Ссылки по теме:
Статья Красносельского К.К. AJAX http://webdesign.site3k.net/consulting/ajax.html