AJAX-проблемы
Сегодня с моим напарником Никитой разбирались, как динамически подгружать инфу на страницу без использования ифрейма. «Конечно, AJAX! » — привычно скажут продвинутые девелоперы и стройными рядами уйдут курить кеды. Фикус в том, что если в динамически подгруженный и отображённый на странице хтмл случайно затешется скрипт на яваскрипте, то он не выполнится. Просто отобразится хтмл и всё. Пример для неверующих:
<div id="output"></div>
<script>
var name = 'output';
var the_div = document.getElementById(name);
if(null!=the_div)
the_div.innerHTML = '<em>some HTML with JavaScripts here
<script>alert(666)<\/script> another one <script xsrc=
"<a title="Linkification: http://ya.ru" class="linkification-ext" href="http://ya.ru/">http://ya.ru</a>"><\/script></em>';
else
alert('cannot find the <div>');
</script>
То бишь есть див, в который подгружается некий хтмл (динамику этой загрузки пока оставим в стороне). Выполнится имеющийся в этом куске хтмля яваскрипт? Фиг.
Что делать? Стали копать исходники, как-то ж люди это делают. Пошли на уважаемый мной сайт dklab.ru и стали рыть пример имеющегося там движка типа AJAX’a. Что выяснили:
- создаётся контейнер (див или спан);
- в него помещается хтмл с одним яваскриптом, причём перед тегом <script> должен быть какой-то текст, а то у ИЕ с этим проблемы;
- далее берётся первый элемент массива скриптов этого контейнера (об этом ниже);
- обновляется его сурс (свойство «src»), что является отмашкой для запуска этого кода.
Посему поэтому приведённый выше код должен быть исправлен так:
<div id="output"></div>
<script>
var name = 'output';
var the_div = document.getElementById(name);
if(null!=the_div)
{
the_div.innerHTML = '<em>some HTML with JavaScripts here
<script>alert(666)<\/script> another one <script xsrc=
"<a title="Linkification: http://ya.ru" class="linkification-ext" href="http://ya.ru/">http://ya.ru</a>"><\/script></em>';
<strong>run_js(name);</strong>
}
else
alert('cannot find the <div>');
</script>
обращаем внимание на выделенный кусок «run_js (name) ». Это специальная функция, которая пробегает по массиву всех имеющихся в указанном контейнере скриптов, благо такая функциональность предоставляется броузером, и обновляем его сурс. Но тут одна загвоздка: если указать тегу script сурс, то автоматически перестаёт работать содержимое тега, просто не запускается. Например:
<script xsrc="<em><a title="Linkification: http://someserver.ua/1.js" class="linkification-ext" href="http://someserver.ua/1.js">http://someserver.ua/1.js</a></em>">
alert(4444);
</script>
Это как в правилах дорожного движения — если есть светофор, то знаки приоритета теряют силу. Таким образом, алерт не запустится, а выполнится только указанный файл.
Теперь вернёмся к проблеме: как обновить сурс так, чтобы:
случай А) если его нет, то он и не появился,
случай Б) если он есть, то изменился так, чтобы указывал на тот же самый файл.
Ответ:
случай А) обновить пустой строкой,
случай Б) приписать ничего не значащий УРЛ-параметр, например, «?1=2» или «&1=2» в зависимости от наличия других параметров.
Так или иначе, вот код многострадальной функции для запуска *статичного* JavaScript:
<script>
function run_js(name)
{
var the_div = document.getElementById(name);
if(null!=the_div)
{
with(the_div)
{
var arr_scripts = the_div.getElementsByTagName("script");
for(i in arr_scripts)
{
var src = arr_scripts[i].src;
if(null!=src)
{
var has_question = (src.indexOf('?', 1)>0 ? true : false );
if(0==src.length)
arr_scripts[i].setAttribute('src', '');
else
arr_scripts[i].setAttribute('src',
arr_scripts[i].src + (has_question==true ? '&' : '?') + '1=1');
}
}
}
}
}
</script>
15 коментарів
Підписатись на коментаріВідписатись від коментарів Коментарі можуть залишати тільки користувачі з підтвердженими акаунтами.