Почему элементы скрипта, созданные через DOMParser, не выполняются?

Я загружаю HTML в Ajax, анализирую его DOMParser и положить все childNodes тела документа во фрагмент документа.

Когда я добавляю фрагмент в тело текущего документа, <script> теги не выполняются.

Я возился и понял, что если я заменю их новыми динамически создаваемыми тегами сценария, они будут выполнены правильно.

Я хотел бы знать, почему?

Например

var html = "Some html with a script <script>alert('test');</script>";

var frag = parsePartialHtml(html);


fixScriptsSoTheyAreExecuted(frag);


document.body.appendChild(frag);


function fixScriptsSoTheyAreExecuted(el) {
  var scripts = el.querySelectorAll('script'),
      script, fixedScript, i, len;

  for (i = 0, len = scripts.length; i < len; i++) {
    script = scripts[i];

    fixedScript = document.createElement('script');
    fixedScript.type = script.type;
    if (script.innerHTML) fixedScript.innerHTML = script.innerHTML;
    else fixedScript.src = script.src;
    fixedScript.async = false;

    script.parentNode.replaceChild(fixedScript, script);
  }
}


function parsePartialHtml(html) {
  var doc = new DOMParser().parseFromString(html, 'text/html'),
      frag = document.createDocumentFragment(),
      childNodes = doc.body.childNodes;

  while (childNodes.length) frag.appendChild(childNodes[0]);

  return frag;
}

Без звонка fixScriptsSoTheyAreExecutedничего не выполнит.

Еще один момент, который мне трудно понять, заключается в том, что если я попытаюсь просто клонировать существующие узлы сценария для создания новых, используя cloneNode, это не работает, какие виды предполагают, что теги сценария, которые были изначально созданы DOMParser несет в себе состояние, которое мешает им быть казненным.

1 ответ

Решение

Это объясняется в спецификации разбора и сериализации DOM:

parseFromString

parseFromString(str, type) Метод должен выполнить эти шаги, в зависимости от типа:

  • "text/html"

    парсить str с HTML parser и верните вновь созданный документ.

    Флаг сценария должен быть установлен на "отключен".

    Заметка
    script элементы помечаются как неисполняемые, а содержимое noscript разбираться как разметка.

Другие вопросы по тегам