256

を使用して、いくつかのスクリプトをページにロードしようとしinnerHTMLました<div>。スクリプトは DOM に読み込まれるように見えますが、実行されることはありません (少なくとも Firefox と Chrome では)。で挿入するときにスクリプトを実行する方法はありinnerHTMLますか?

サンプルコード:

<!DOCTYPE html>
<html>
  <body onload="document.getElementById('loader').innerHTML = '<script>alert(\'hi\')<\/script>'">
    Shouldn't an alert saying 'hi' appear?
    <div id="loader"></div>
  </body>
</html>

4

25 に答える 25

106

すべてのスクリプトを実行可能なスクリプトに再帰的に置き換える方法を次に示します。

function nodeScriptReplace(node) {
        if ( nodeScriptIs(node) === true ) {
                node.parentNode.replaceChild( nodeScriptClone(node) , node );
        }
        else {
                var i = -1, children = node.childNodes;
                while ( ++i < children.length ) {
                      nodeScriptReplace( children[i] );
                }
        }

        return node;
}
function nodeScriptClone(node){
        var script  = document.createElement("script");
        script.text = node.innerHTML;

        var i = -1, attrs = node.attributes, attr;
        while ( ++i < attrs.length ) {                                    
              script.setAttribute( (attr = attrs[i]).name, attr.value );
        }
        return script;
}

function nodeScriptIs(node) {
        return node.tagName === 'SCRIPT';
}

呼び出しの例:

nodeScriptReplace(document.getElementsByTagName("body")[0]);
于 2013-12-14T14:20:25.373 に答える
106

DOM テキストとして挿入したスクリプト コードを実行するには、 eval()を使用する必要があります。

MooTools はこれを自動的に行います。jQuery も同様に行うと確信しています (バージョンによって異なります。jQuery バージョン 1.6+ では が使用されますeval)。<script>これにより、タグを解析してコンテンツをエスケープする手間や、その他の「問題」が大幅に軽減されます。

通常、自分で作成する場合は、適切に動作しないため、eval()などの HTML マークアップなしでスクリプト コードを作成/送信する必要があります。<script>eval()

于 2009-07-29T01:04:25.300 に答える
97

ここにあなたの問題に対する非常に興味深い解決策があります: http://24ways.org/2005/have-your-dom-and-script-it-too

したがって、script タグの代わりにこれを使用します。

<img src="empty.gif" onload="alert('test');this.parentNode.removeChild(this);" />

于 2010-09-15T03:07:44.393 に答える
49

スクリプトを作成してから、コンテンツを挿入できます。

var g = document.createElement('script');
var s = document.getElementsByTagName('script')[0];
g.text = "alert(\"hi\");"
s.parentNode.insertBefore(g, s);

これはすべてのブラウザで機能します:)

于 2011-08-14T00:36:57.703 に答える
30

このコードを使用しましたが、正常に動作しています

var arr = MyDiv.getElementsByTagName('script')
for (var n = 0; n < arr.length; n++)
    eval(arr[n].innerHTML)//run script inside div
于 2013-04-29T12:04:56.163 に答える
5

を使用してスクリプトを挿入することはできませんが、とinnerHTMLを使用して文字列をスクリプト タグにロードすることは可能です。BlobURL.createObjectURL

文字列をスクリプトとして実行し、promise を通じて返されるスクリプトの「エクスポート」を取得できる例を作成しました。

function loadScript(scriptContent, moduleId) {
    // create the script tag
    var scriptElement = document.createElement('SCRIPT');

    // create a promise which will resolve to the script's 'exports'
    // (i.e., the value returned by the script)
    var promise = new Promise(function(resolve) {
        scriptElement.onload = function() {
            var exports = window["__loadScript_exports_" + moduleId];
            delete window["__loadScript_exports_" + moduleId];
            resolve(exports);
        }
    });

    // wrap the script contents to expose exports through a special property
    // the promise will access the exports this way
    var wrappedScriptContent =
        "(function() { window['__loadScript_exports_" + moduleId + "'] = " + 
        scriptContent + "})()";

    // create a blob from the wrapped script content
    var scriptBlob = new Blob([wrappedScriptContent], {type: 'text/javascript'});

    // set the id attribute
    scriptElement.id = "__loadScript_module_" + moduleId;

    // set the src attribute to the blob's object url 
    // (this is the part that makes it work)
    scriptElement.src = URL.createObjectURL(scriptBlob);

    // append the script element
    document.body.appendChild(scriptElement);

    // return the promise, which will resolve to the script's exports
    return promise;
}

...

function doTheThing() {
    // no evals
    loadScript('5 + 5').then(function(exports) {
         // should log 10
        console.log(exports)
    });
}

これを実際の実装から単純化したので、バグがないという保証はありません。しかし、原則は機能します。

スクリプトの実行後に値を取得する必要がない場合は、さらに簡単です。Promiseビットとビットを省略しonloadます。window.__load_script_exports_スクリプトをラップしたり、グローバルプロパティを作成したりする必要さえありません。

于 2016-11-04T15:21:11.957 に答える
3

はい、できますが、DOM の外で行う必要があり、順序が正しい必要があります。

var scr = '<scr'+'ipt>alert("foo")</scr'+'ipt>';
window.onload = function(){
    var n = document.createElement("div");
    n.innerHTML = scr;
    document.body.appendChild(n);
}

...「foo」に警告します。これはうまくいきません:

document.getElementById("myDiv").innerHTML = scr;

ノードが最初に挿入されるため、これでも機能しません。

var scr = '<scr'+'ipt>alert("foo")</scr'+'ipt>';
window.onload = function(){
    var n = document.createElement("div");
    document.body.appendChild(n);
    n.innerHTML = scr;  
}
于 2009-07-29T12:23:05.107 に答える
1

$(parent).html(code)の代わりに使用しparent.innerHTML = codeます。

以下は、属性document.writeを介してロードされたスクリプトとスクリプトを使用するスクリプトも修正します。src残念ながら、これでも Google AdSense スクリプトでは機能しません。

var oldDocumentWrite = document.write;
var oldDocumentWriteln = document.writeln;
try {
    document.write = function(code) {
        $(parent).append(code);
    }
    document.writeln = function(code) {
        document.write(code + "<br/>");
    }
    $(parent).html(html); 
} finally {
    $(window).load(function() {
        document.write = oldDocumentWrite
        document.writeln = oldDocumentWriteln
    })
}

ソース

于 2014-05-07T08:27:04.810 に答える
-1

innerHTMLから(Javaスクリプト)タグを実行します

スクリプト要素をクラス属性class="javascript"を持つdivに置き換え、次のように閉じます</div>

実行するコンテンツを変更しないでください(以前はスクリプトタグにありましたが、現在はdivタグにあります)

ページにスタイルを追加...

<style type="text/css"> .javascript { display: none; } </style>

次に、jqueryを使用してevalを実行します(Jquery jsはすでに含まれている必要があります)

   $('.javascript').each(function() {
      eval($(this).text());

    });`

あなたは私のブログで、ここでもっと探検することができます。

于 2013-01-22T14:29:12.847 に答える