Как и когда браузеры реализуют изменения в DOM документа в реальном времени?

Мой веб-сайт динамически встраивает внешний файл Javascript в тег заголовка. Внешний Javascript определяет глобальную переменную myString = "data". В какой момент myString становится доступным для Javascript на веб-сайте?

<html>
<head>
    <script type="text/javascript">
        myString = null;
        external = document.createElement("script");
        //externalScript.js is one line, containing the following:
        //myString = "data";
        external.setAttribute("src", "externalScript.js");
        external.setAttribute("type", "text/javascript");
        document.getElementsByTagName("head")[0].append(external);
        alert(myString);
    <script>
</head>
<body>
</body>
</html>

Этот код выдает нулевое значение (хотя я думал, что оно выдаст предупреждение «данные») в Chrome и IE, даже несмотря на то, что в этот момент DOM уже загружен в externalScript.js. Когда браузер фактически оценивает externalScript.js и в какой момент у меня есть доступ к новому значению myString?


person Mark    schedule 30.05.2010    source источник


Ответы (1)


Вы можете получить к нему доступ, когда для этого элемента сценария срабатывает событие onload, например:

external = document.createElement("script");
external.onload = function() { alert(myString); };
script.onreadystatechange= function () { //for IE, the special kid...
  if (this.readyState == 'complete') alert(myString);
}
external.setAttribute("src", "externalScript.js");
external.setAttribute("type", "text/javascript");
document.getElementsByTagName("head")[0].appendChild(external);

Это просто прикрепляет функцию для запуска после загрузки этого скрипта, выполнения любого кода, который зависит от скрипта. Исправление к предыдущему ответу: как указывает seanmonstar в комментариях (спасибо!), вам действительно нужно исключение IE здесь снова, потому что он какой-то "особенный"...

person Nick Craver    schedule 30.05.2010
comment
О, мне так больше нравится. Ответ удален. Будет ли вообще работать внедрение внешнего скрипта, если мы действуем внутри <head>? Я не особо занимался этим... - person Matchu; 30.05.2010
comment
@Matchu - так и должно быть, пока элемент открыт, он будет работать ... браузеры, я бы предположу, знали, что такое происходит. Когда элемент открыт, большинство реализаций браузера рассматривают его как закрытый элемент, добавляя дочерние элементы к этому родителю по мере их нахождения, но сам родитель становится честной игрой, как только он открыт. - person Nick Craver; 30.05.2010
comment
Я думаю, что столкнулся с проблемами со сценариями в конце <body>, когда можно было что-то добавить... пора проверить! - person Matchu; 30.05.2010
comment
Вам также необходимо проверить onreadystatechange для IE. вот так: stackoverflow.com/questions/903012/ - person seanmonstar; 30.05.2010
comment
@seanmonstar: Спасибо - обновлено, чтобы включить это в приветствие. Это еще раз, почему я использую уровень абстракции... Я думаю, вы не можете предположить, что что-то будет работать в IE, как в остальном мире браузеров... - person Nick Craver; 30.05.2010
comment
@Nick Craver - Спасибо за ответ. У меня только одна маленькая проблема. W3C DOM API, похоже, не упоминает загрузку атрибутов для элементов или узлов. Где я могу найти документацию о том, как это работает? - person Mark; 30.05.2010
comment
@Mark - Вы можете использовать MSDN для некоторых из них Я не уверен, что это в API (не там, где я могу его получить в данный момент)... что объясняет несоответствие с IE. Не совсем описание API, но хорошее изложение того, как это работает, посмотрите здесь: unixpapa .com/js/dyna.html - person Nick Craver; 30.05.2010
comment
@Nick Craver - первая ссылка была полезной и показывает способ имитировать прослушиватель событий без использования загрузки. Просто примечание к MSDN, также предполагается, что ‹script ... onload=handler›...‹/script› сработает после загрузки скрипта. Это говорит о том, что вы также сможете сделать это: external.setAttribute(onload, alert('myString');); Сценарии, однако, не могут иметь атрибут onload в соответствии с XHTML dtds, поэтому такие вещи фактически нарушают XHTML-валидность документа. Если external.onload является ярлыком для external.getAttribute(onload), ваш способ аннулирует XHTML. - person Mark; 30.05.2010
comment
продолжение: Однако, если element.onload — это просто метод, который браузер вызывает после загрузки элементов, проблем нет. Поэтому мне просто интересно, связана ли загрузка объекта Javascript с DOM. - person Mark; 30.05.2010
comment
@Mark - атрибуты и обработчики событий - это две очень разные вещи, например, onclick не является атрибутом, это может быть обработчик событий, объявленный так же, как атрибут в разметке (хотя это плохая практика и вообще другое обсуждение), но это разные вещи. Вы никогда не прикрепите обработчики событий в виде атрибутов, поэтому не выбирайте, какие атрибуты разрешены... атрибуты, обработчики событий и методы DOM - это 3 отдельных, хотя и перекрывающихся понятия. - person Nick Craver; 30.05.2010
comment
@Nick Craver - Ладно, попался. Объявление обработчика событий с помощью разметки — шаткий способ объявления обработчика событий. (И это делает ваш XHTML недействительным). - person Mark; 30.05.2010