Блог Александра Башкирова

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

Ajax

Подписаться на эту метку по RSS

AJAX без AJAX или кое-что об IFRAME

Просмотров: 6844Комментарии: 0
Alib.spb.ru

Внимание! Данная статья скорее всего устарела и описываемое ниже имеет больше академичсекий интерес.

Для начала. Все началось с того, что, заинтересовавшись 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