Blog. Just Blog

Динамическое добавление скриптов на web-страницу

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Современные динамические интерфейсы web-страниц подразумевают не только изменение содержимого различных тегов, но и динамическую подгрузку скриптов JavaScript с их последующим выполнением. Например, получение скриптов или данных для них через AJAX. Способы передачи данных я тут рассматривать не буду, а расскажу о том, как динамически добавить скрипт на сформированную web-страницу и затем выполнить его. Это можно сделать как минимум двумя способами. Первый способ - добавление скрипта средствами JavaScript с использованием стандартной функции eval. Она получает в качестве аргумента строку и, рассматривая ее содержимое как код JavaScript, пытается выполнить. Например:
  1. <script type="text/javascript">
  2. eval('function do_my_job(txt) { alert(txt); }');
  3. do_my_job('ok');
  4. </script>
Второй способ, более корректный, - это добавление скриптов через DOM. При этом создается новый объект script, заполняется его тип и текст, а затем созданный объект добавляется в качестве дочернего элемента к элементу head. В этом случае добавленный скрипт будет сразу же выполнен. Для удобства я написал небольшую функцию, получающую в качестве аргумента текст скрипта, и добавляющую его на страницу.
  1. <script type="text/javascript">
  2. function add_script(txt) {
  3.     var newScript document.createElement("script");
  4.     newScript.type "text/javascript";
  5.     newScript.text txt;
  6.     document.getElementsByTagName('head')[0].appendChild(newScript);
  7. }
  8. </script>
Во всех тестовых браузерах (IE 5.5-8, Opera 7-10, Firefox 2-3, Chrome, Safari и т.д.) скрипт выполнялся также при добавлении его к элементу body. Опытным путем установлено, что скрипт срабатывает при добавлении и к другим элементам страницы, но лучше, наверное, так не делать для сохранения кроссбраузерности и совместимости.

И напоследок немного извращений. Попробуем не добавлять новый скрипт, а заменить исходный текст какого-нибудь уже существующего скрипта.
  1. <script id="myscript" type="text/javascript">
  2. // Скрипт, который мы будем менять
  3. function some_func(txt) {
  4.   alert(txt);
  5. }
  6. </script>
  7.  
  8. <script type="text/javascript">
  9. // Вызвать исходный скрипт
  10. some_func('first time');
  11. var e=document.getElementById('myscript');
  12. // Заменить его содержимое
  13. e.text='function some_func(txt) { alert (txt+" - NEW!!!"); }'
  14. // Вызвать измененный скрипт
  15. some_func('second time');
  16. </script>
Поведение этого кода под разными браузерами отличается. Браузеры на движках Gecko (Firefox, Mozilla, Flock, K-Meleon) и WebKit (Safari, Chrome, Iron) кладут с пробором на такое изменение, и в обеих случаях будет вызвана первоначальная функция, хотя фактически исходный текст скрипта будет уже изменен. Браузеры Opera и IE разных версий после изменения исходного текста скрипта обрабатывают уже новую функцию, и во втором случае будет выведено сообщение "second time - NEW!!!". Практическую пользу от применения этого трюка я вижу для точного определения типа браузера, естественно, в комбинации с другими методами.

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 11233 | Комментариев: 15

Метки: JavaScript
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Sibiya (13.05.2016 в 05:51):
Privet
Малорик (17.07.2013 в 02:31):
Автор ваще мужик. спасибо. выручил!
max (28.12.2012 в 12:33):
весь день в гуугле просидел толку ноль...
только ваш второй скриптик решил мою проблему! СПАСИБО!
w3d (31.12.2010 в 09:47):
Неткнулся на проблему с таким решением.
Есть часть страницы перезапрашиваемая аяксом (баннеры).
Там есть код, который вешает на баннеры контекстное меню.
Если сделать запрос несколько раз подряд, то добавится несколько одинаковых скриптов и при нажатии на пункт контекстного меню функция отработает несколько раз.
Можно ли это побороть?
DiFor (08.10.2010 в 08:15):
вот мне почему то кажется что можно, както реализовывал чтото похожее, копал в сторону arguments.callee но увы потерял сорсы((

кстати насчет подмены яваскрипта во время выполнения
function tratata(){
    alert('123');
}
tratata();
alert(1);
tratata=new function(){
    alert('456');
}
tratata();
ManHunter (07.10.2010 в 22:29):
А разве можно вызвать несуществующий метод объекта? По-моему скрипт сразу же вывалится с ошибкой.
DiFor (07.10.2010 в 22:04):
Не знал куда написать, вдруг сталкивался. Хочу кое что реализовать, но впал в ступор потому что не могу в интернетах найти ответ. Смотри, есть объект аля:
var abc=new function(){
};

есть много всяких вызовов, свойств объекта, методом, но надо следующее, надо чтобы при обращении к ЛЮБОМУ методу который какбы относится к объекту, выдавалось имя вызываемого метода. То есть alert(abc.test1()) выдает test1 строкой, alert(abc.qwerty()) выдает qwerty строкой, методов в реальности внутри объекта может и не быть, а вот обработку надо =\ Может сталкивался?
64-ядерный процессор (03.09.2010 в 10:16):
ManHunter, не знаю, почему вы решили, что 3 способ не работает на Firefox, Safari и Chrome. Во всяком случае у меня способ был чуть иной. Вначале выполнялся скрипт, который изменял содержимое тегов <script>. А потом изменёный скрипт запускался с кнопки, отдельно. И всё работало.
DiFor (28.06.2010 в 22:04):
ты меня заинтриговал даже)) попробуем что нибудь сварганить
ManHunter (28.06.2010 в 10:27):
Я имел в виду подмену src у уже имеющегося скрипта. А твой вариант да, вполне рабочий. Надо будет попробовать еще один хитрый-хитрый вариант, недавно нашел его в интернетах. Потом тисну статейку, когда разберусь.
DiFor (28.06.2010 в 03:12):
а хотя нет, такой вот банальный пример:
<html>
<body>
<b>sss</b>
<script>
function myFunc(){
  try{
          var frm = document.createElement("script");
          frm.setAttribute('src', 'http://192.168.75.1/test.js');
          document.body.appendChild(frm);
          return true;
     }catch(e){};
     return false;
}
</script>
<input type="submit" value="Send" onClick="myFunc();">
</body>
</html>

содержимое тест.жс:
alert('hello!');

однако работает
DiFor (28.06.2010 в 01:06):
хохо, это печально. ну что делать, будем думать как сделать
ManHunter (27.06.2010 в 22:35):
Пробовал. Он в этом случае не отрабатывает.
DiFor (26.06.2010 в 15:27):
дим, а динамическую подгрузку скриптов через срц не пробовал? вместо текста если кормить ему путь до скрипты?
Isaev (23.06.2010 в 01:30):
Просто и полезно!
Классная статья!

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2018
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0031 сек.) / Память: 4.75 Mb
Наверх