vytvoření značky skriptu pomocí innerHTML prvku div nefunguje

Tohle bylo triviální.

Jak je uvedeno ve specifikaci (8.4 Analýza fragmentů HTML a 8.2.3.5 Jiné příznaky stavu analýzy), citovat:

při použití innerHTML prohlížeč bude

  1. Vytvořte nový uzel Dokument a označte jej jako dokument HTML.

  2. Pokud existuje kontextový prvek a dokument kontextového prvku je v režimu quirks, nechte Dokument v režimu quirks. V opačném případě, pokud existuje kontextový prvek a prvek Document of thecontext je v režimu omezených quirků, pak nechte dokument v režimu neomezených vtipů. V opačném případě ponechte dokument v režimu bez výstředností.

  3. Vytvořte nový analyzátor HTML a přiřaďte jej k právě vytvořenému uzlu Document....

a při analýze <script> uvnitř

Příznak skriptování je nastaven na "enabled", pokud bylo skriptování povoleno pro dokument, ke kterému je analyzátor přidružen, když byl analyzátor vytvořen, a v opačném případě na "disabled".

Příznak skriptování lze povolit, i když byl analyzátor původně vytvořen pro algoritmus analýzy fragmentů HTML, i když se v takovém případě skriptové prvky nespustí.

Nebude tedy spuštěn, pokud do něj vložíte innerHTML .

A pomocí innerHTML zabrání <script> prvek vytvořený z trvalého provádění.

Jak je uvedeno ve specifikaci (4.3.1 Element script,) quote:

Dynamická změna atributů src, type, charset, async a defer nemá žádný přímý účinek; tyto atributy se používají pouze v určitých časech popsaných níže.

Na závěr níže popsané to znamená, že analyzuje pouze src atribut při vstřikování <script> na document (bez ohledu na to, včetně dočasného vytvořeného při použití innerHTML .)

Pokud tedy chcete do dokumentu vložit skript a spustit jej, musíte použít script = document.createElement('script') .

Nastavte jeho atributy jako src a type , případně obsah uvnitř (pomocí script.appendChild(document.createTextNode(content)) ), pak jej připojte k document.body .


Místo toho můžete zkusit toto:

var wrap = document.createElement('div');
var scr = document.createElement('script');
scr.src = scriptUrl;
scr.type = 'text/javascript';
wrap.appendChild(scr);
document.body.appendChild(wrap);

Vytvořením značky skriptu explicitně říkáte JS, že innerHTML není text, ale je to spustitelný skript.


Možné řešení, když nemáte kontrolu nad mechanismem vkládání a jste nuceni používat innerHTML s script beacons, je přestavět DOM uzly z těch "duchů".

Toto je opakující se problém v odvětví reklamních technologií, ve kterém mnoho automatizovaných systémů duplikuje libovolný HTML kód (aka. adservers ^^).

v Chrome funguje dobře:

var s = wrap.getElementsByTagName('script');
for (var i = 0; i < s.length ; i++) {
  var node=s[i], parent=node.parentElement, d = document.createElement('script');
  d.async=node.async;
  d.src=node.src;
  parent.insertBefore(d,node);
  parent.removeChild(node);
}

(můžete to otestovat v JSFiddle)


No