9

JSコードは次のとおりです。

var wrap = document.createElement("div");
wrap.innerHTML = '<script type="text/javascript" src="'+scriptUrl+'"></script>';
var wrapscript = wrap.childNodes[0];
document.body.appendChild(wrapscript)

本文はスクリプト要素を挿入しましたが、JS リソースは読み込まれず、http 要求さえありません。

誰かがなぜこれが起こっているのか説明できますか?

問題は Zeptojs の $ メソッドにあります

$('<script type="text/javascript" src="'+scriptUrl+'"></script>').appendTo($("bdoy"))

上記のコードのように動作し、バグを引き起こします。

4

3 に答える 3

24

これは些細なことでした。

仕様 ( 8.4 Parsing HTML fragmentおよび8.2.3.5 Other parsing state flags ) で述べられているように、以下を引用します。

innerHTMLブラウザを使用する場合

  1. 新しいドキュメント ノードを作成し、それを HTML ドキュメントとしてマークします。

  2. コンテキスト要素があり、コンテキスト要素の Document が quirks モードの場合、Document を quirks モードにします。それ以外の場合、コンテキスト要素があり、コンテキスト要素のドキュメントが限定互換モードの場合、ドキュメントを限定互換モードにします。それ以外の場合は、ドキュメントを非互換モードのままにします。

  3. 新しい HTML パーサーを作成し、作成したばかりの Document ノードに関連付けます。...

<script>内部を解析するとき

パーサーが作成されたときにパーサーが関連付けられているドキュメントに対してスクリプトが有効になっている場合、スクリプト フラグは「有効」に設定され、それ以外の場合は「無効」に設定されます。

スクリプト フラグは、パーサーが元々 HTML フラグメント解析アルゴリズム用に作成された場合でも有効にすることができます (その場合、スクリプト要素は実行されません)。

で注入する限り、実行されませんinnerHTML

また、使用すると、作成され要素が永続的に実行されるのinnerHTMLを防ぎます。 <script>

仕様 ( 4.3.1 The script element ) に記載されているように、引用:

src、type、charset、async、および defer 属性を動的に変更しても、直接的な影響はありません。これらの属性は、以下で説明する特定の時間にのみ使用されます。

以下で説明する結論は、をsrcに注入するときにのみ属性を解析するということです (を使用したときに作成された一時的なものを含め、どれであっても)。<script>documentinnerHTML

そのため、ドキュメントにスクリプトを挿入して実行したい場合は、 を使用する必要がありますscript = document.createElement('script')

srcとのような属性を設定しtype、場合によっては ( を使用して) 内部の内容を設定しscript.appendChild(document.createTextNode(content))、 に追加しますdocument.body

于 2012-11-15T06:57:33.027 に答える
4

代わりにこれを試すことができます:

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

スクリプトタグを明示的に作成することで、innerHTMLはテキストではなく、実行可能なスクリプトであることをJSに伝えます。

于 2012-11-15T02:41:10.330 に答える
4

挿入メカニズムを制御できず、scriptビーコンで innerHTML を使用せざるを得ない場合に考えられる解決策は、「ゴースト」ノードから DOM ノードを再構築することです。

これはアドテク業界で繰り返される問題であり、多くの自動化されたシステムが任意の HTML コードを複製します (別名、アドサーバー ^^)。

Chromeで正常に動作します:

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);
}

( JSFiddle でテストできます)

于 2014-09-26T13:46:18.903 に答える