私は最近 iframe にスクリプトを挿入し、jQuery の .append() メソッドと DOM appendChild() メソッドの違いを発見しました。 DOM API の appendChild() メソッドによって挿入された 3f1c4e4b6b16bbbd69b2ee476dc4f83a が実行されます。 iframe のコンテキスト内 jQuery(2.2) .append() メソッドによって挿入された スクリプトの実行コンテキストは常に現在のウィンドウ内にあります </li> </ul> <p>実際、jQuery .append() メソッドは3f1c4e4b6b16bbbd69b2ee476dc4f83a の特別な処理: スクリプトの内容を取得します。そして、スクリプトは eval() を通じて現在のスコープで実行され、ブラウザーのデフォルトのスクリプト実行スケジュールは無効になります。 </p> <h2>最初に例を見てください</h2> <p>親コンテナの window.id="parent" を設定し、iframe に挿入されたスクリプトで出力します。 コンテキストが親コンテナと共有されている場合は、「parent」が出力されます。それ以外の場合は、未定義にする必要があります。 </p> <p> <pre class="sycode" name="code">window.id = 'parent';var idocument = $('iframe').prop('contentDocument');var injected_script = 'console.log("window.id ==", window.id)';</pre> </p> <p> 3f1c4e4b6b16bbbd69b2ee476dc4f83a タグを作成し、document.body.appendChild() メソッドを使用して以下を挿入します: </p> <p> <pre class="sycode" name="code">var el = idocument.createElement('script');el.text = injected_script;idocument.body.appendChild(el);</pre> </p> <p> 出力は次のようになります: window.id == unknown、スコープが分離されていることを示します。 jQuery .append() メソッドを使用して挿入します。 </p> <p> <pre class="sycode" name="code">var el = idocument.createElement('script');el.text = injected_script;$(idocument.body).append(el);</pre> </p> <p> 出力は次のとおりです: window.id ==parent 明らかに、jQuery は単に appendChild() を呼び出すだけでなく、他の処理も行います。 jQueryのソースコードを見てみましょう。 </p> <h2>スクリプトタグを無効にする</h2> <p> jQuery ソースコードは Github でアクセスできます。このファイルを参照してください:manipulation.js。 実際に 3f1c4e4b6b16bbbd69b2ee476dc4f83a タグを挿入する前に、domManip メソッドを入力します。 すべての 3f1c4e4b6b16bbbd69b2ee476dc4f83aスクリプトを取得し、disableScript 関数を使用して無効にします。 </p> <p> <pre class="sycode" name="code">function domManip( collection, args, callback, ignored ) // ... if ( first || ignored ) { scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); hasScripts = scripts.length; // ... callback.call( collection[ i ], node, i );</pre> </p> <p> disableScript スクリプトを無効にできるとしたらどうしますか?参照してください: </p> <p> <pre class="sycode" name="code">function disableScript( elem ) { elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; return elem;}</pre> </p> <p> type="text/javascript が設定されているスクリプトの場合、そのタイプは type = "true/text/javascript" に書き換えられます; タイプが設定されていないスクリプトの場合、そのタイプは false / に書き換えられます。つまり、ブラウザはタグをページ スクリプトとして認識しなくなり、ブラウザによる 3f1c4e4b6b16bbbd69b2ee476dc4f83a </p> DOM ノードの挿入<h2> の実行が禁止されます。その後、domManip からのコールバックが実際に .append() メソッドに入ることができます。 .append() が DOM API appendChild を介して実装されていることを確認してください。3f1c4e4b6b16bbbd69b2ee476dc4f83a のタイプは、 </h2> <p> <pre class="sycode" name="code">jQuery.fn.extend( { // ... append: function() { return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.appendChild( elem ); } } ); },</pre> </p> <p>eval スクリプトの実行時に自動的に実行されません。 </p> <h2> コールバックが戻ったら、再び doManip 関数に戻り、DOMEval を呼び出してスクリプトのコンテンツを実行します。 </h2> <p> <pre class="sycode" name="code">function domManip( collection, args, callback, ignored ) { // ... callback.call( collection[ i ], node, i ); // ... if ( node.src ) { if ( jQuery._evalUrl ) { jQuery._evalUrl( node.src ); } } else { jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); }</pre> </p> <p> jQuery.globalEval() は最後に JavaScript eval を呼び出してスクリプトを実行します。そのため、スクリプト コンテキストはウィンドウ内にあります。 jQuery は次のとおりです。 ソース コード: core.js </p> <p> <pre class="sycode" name="code">jQuery.extend( { // ... globalEval: function( code ) { var script, indirect = eval; code = jQuery.trim( code ); if ( code ) { if ( code.indexOf( "use strict" ) === 1 ) { script = document.createElement( "script" ); script.text = code; document.head.appendChild( script ).parentNode.removeChild( script ); } else { indirect( code ); } } },</pre> </p> <p> jQuery の最新の master ブランチでは、最終的に domManip() メソッドが globalEval の代わりに DOMEval を呼び出すようになり、globalEval も domEval として実装されます。 (master/core.js を参照)、JavaScript eval() は使用されなくなりました </p> <p> <pre class="sycode" name="code">// manipulation.jsDOMEval( node.textContent.replace( rcleanScript, "" ), doc );// core.jsglobalEval: function( code ) { DOMEval( code );}</pre> </p> <p> </p>。