Как всегда, начнем с того что есть браузеры, а есть IE. Да, я не люблю его, по той причине, что приходится всегда находить альтернативные и не всегда очевидные способы решения задач, которые в том же Хроме делаются на раз-два-три. Но вернемся к сути.
Итак, допустим есть скрипт 'dynamic.js' и если бы мы просто решили его вставить, то это выглядело бы вот так
<script type="text/javascript" src="dynamic.js"></script>
Но наша задаче - сделать все динамически - создадим тэг <script> и добавим его в <head>
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'dynamic.js';
head.appendChild(script);
Проверено, что это работает в IE 5.0 и 7.0; Firefox 2.0; Safari 1.3; Opera 7.54 и 9.10; Konqueror 3.5; iCab 3.0.
Есть еще один простой способ сделать то же самое. Изначально создаем тэг <script>
<script id="loadarea" type="text/javascript"></script>
а потом в коде делаем следующий вызов
document.getElementById('loadarea').src= 'dynamic.js';
К сожалению, такой способ работает уже не везде. Он применим в Windows IE, Opera и iCab ,а вот в остальных браузерах уже как повезет.
Усложним нашу задачу - нужно вызвать какой-то метод из загруженного файла. Реализация будет выглядеть вот так
script.onreadystatechange= function () {
if (this.readyState == 'complete') doSmth();
}
script.onload= doSmth;
Или если все вместе
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.onreadystatechange= function () {
if (this.readyState == 'complete') doSmth();
}
script.onload= doSmth;script.src= 'dynamic.js';
head.appendChild(script);
И вот тут уже есть немного магии. Вызов script.onload предназначен для не IE браузеров, так как согласно спецификациям работает onreadystatechange только в IE. Ложь и клевета - везде оно уже работает, другое дело, что могут readyState различаться. Всего их 5 видов:
0 | uninitialized |
1 | loading |
2 | loaded |
3 | interactive |
4 | complete |
Но вот в разных браузерах возникают разные состояния. Например в том же хроме у меня стабильно возникал complete, а в IE он возник всего один раз, зато стабильно возникали loading и loaded. С учетом этого финальный код будет выглядеть вот так:
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.onreadystatechange= function () {
if (this.readyState == 'complete' || this.readyState == 'loaded') doSmth();
}
script.onload= doSmth;
script.src= 'dynamic.js';
head.appendChild(script);
var script= document.createElement('script');
script.type= 'text/javascript';
script.onreadystatechange= function () {
if (this.readyState == 'complete' || this.readyState == 'loaded') doSmth();
}
script.onload= doSmth;
script.src= 'dynamic.js';
head.appendChild(script);
Есть и еще один способ - вместо указания урла скрипта, указать сам его код
var script = document.createElement('script');
var scr = 'alert("bah");';
var tag = document.createTextNode(scr);
script .appendChild(tag);
var head = document.getElementsByTagName('head')[0];
head.appendChild(script);
Такой вариант у меня возник, когда я пытался сделать динамическую загрузку для Pocket IE 6.0. К сожалению ни один вариант в нем так и не заработал. Пришлось звать на помощь jsp и делать вот так:
<%
String[] strings = request.getRequestURI().split("/");
String scriptUrl = "/"+strings[1]+"/dynamic.js";
%>
<%="<SCRIPT TYPE=\"text/javascript\" charset=\"utf-8\" src=\""+scriptUrl+"\"></SCRIPT>"%>
Надеюсь, данный пост пригодится вам при решении подобной проблемы.
Комментариев нет:
Отправить комментарий