4

スクリプト ブロックをドキュメントに動的に追加しようとしています。これを行うと、スクリプト ブロックが実行されません。

<body>
    <div id="dynamicDiv">
    </div>

    <script type="text/javascript">
        var elem = document.getElementById("dynamicDiv");
        var tmpStr = "<script type=\"text\/javascript\"> ";
        tmpStr += "function hello (val)";
        tmpStr += "{";
        tmpStr += "alert('hello ' + val);";
        tmpStr += "}";
        tmpStr += "<\/script>";

        elem.innerHTML = tmpStr;

        hello("World");
    </script>
</body>

上記のコードは機能しません。別の投稿 (動的にロードされた JavaScript ブロックをどのように実行しますか? ) で、innerHTML にスクリプトを追加すると実行されないという回答を見ました。innerHTML を直接使用する代わりに、この innerHTML で div を作成し、appendChild を使用してスクリプトを追加します。

<body>
    <div id="dynamicDiv">
    </div>

    <script type="text/javascript">
        var elem = document.getElementById("dynamicDiv");
        var tmpStr = "<script type=\"text\/javascript\"> ";
        tmpStr += "function hello (val)";
        tmpStr += "{";
        tmpStr += "alert('hello ' + val);";
        tmpStr += "}";
        tmpStr += "<\/script>";

        var newdiv = document.createElement('div');
        newdiv.innerHTML = tmpStr;

        elem.appendChild(newdiv);

        hello("World");
    </script>
</body>

しかし、この解決策も私にはうまくいきませんでした。

別の返信で、スクリプト要素を取得し、eval を使用して実行する必要があることを再度確認しました。

<body>
    <div id="dynamicDiv">
    </div>

    <script type="text/javascript">
        var elem = document.getElementById("dynamicDiv");
        var tmpStr = "<script type=\"text\/javascript\"> ";
        tmpStr += "function hello (val)";
        tmpStr += "{";
        tmpStr += "alert('hello ' + val);";
        tmpStr += "}";
        tmpStr += "<\/script>";

        var newdiv = document.createElement('div');
        newdiv.innerHTML = tmpStr;

        elem.appendChild(newdiv);

        var scripts = newdiv.getElementsByTagName('script');
        for (var ix = 0; ix < scripts.length; ix++) {
            eval(scripts[ix].text);
        }

        hello("World");
    </script>
</body>

このソリューションは私にとってはうまくいきます。

しかし、これを関数で行うと、機能しません。

<body>
    <div id="dynamicDiv">
    </div>

    <script type="text/javascript">

        function createFunction(){
            var elem = document.getElementById("dynamicDiv");
            var tmpStr = "<script type=\"text\/javascript\"> ";
            tmpStr += "function hello (val)";
            tmpStr += "{";
            tmpStr += "alert('hello ' + val);";
            tmpStr += "}";
            tmpStr += "<\/script>";

            var newdiv = document.createElement('div');
            newdiv.innerHTML = tmpStr;

            elem.appendChild(newdiv);

            var scripts = newdiv.getElementsByTagName('script');
            for (var ix = 0; ix < scripts.length; ix++) {
                eval(scripts[ix].text);
            }   
            hello("World 1");
        }

        createFunction();
        hello("World 2");
    </script>
</body>

スクリプトが評価された後、関数が使用可能であることがわかります。関数 createFunction で使用できます。createFunction() スコープ外では、hello() は使用できません。

私は何を間違っていますか?非常に基本的なものが欠けていますか?確認して助けてください。

ありがとう、ポール

PS私はjQueryを使用していません。これをテストするためにクロムを使用しています。

4

2 に答える 2

2

あなたが提供した 3 番目のスニペットが for ループ内では機能するが、外部では機能しない理由は、eval. eval文字列を受け取り、それを js として実行します。これがループ内で動作している理由ですが、使用evalすると将来の使用のために解析されないため、他の場所では使用できなくなります。したがって、ループの外で呼び出すと、参照エラーが発生します。

アップデート:

タグを含む文字列を取得する場合は<script>、スクリプト タグを解析するだけです。

var string = "<script type=\"text\/javascript\"> ";
    string += "function hello (val)";
    string += "{";
    string += "alert('hello ' + val);";
    string += "}";
    string += "<\/script>";
string = string.replace(/<(script|\/script).*?>/g,'');
function createFunction() {
    var elem = document.getElementById("dynamicDiv");
    var script = document.createElement('script');
    script.innerHTML = string;
    elem.appendChild(script);
    hello("World 1");
}
createFunction()
hello('world 2');

JSFiddle: http://jsfiddle.net/3wYD6/

これの要点はよくわかりませんが、本当にこれをやりたい場合は、新しいスクリプト要素を作成し、それを innerHTML に関数に設定してから、新しいスクリプトを div に追加します。

var elem = document.getElementById("dynamicDiv"),
    script = document.createElement('script');
script.innerHTML = 
    'function hello (val) {' +
        'alert("hello " + val);' + 
    '}';
elem.appendChild(script);
hello('world');
于 2013-03-22T10:42:47.280 に答える
0

最初の試行では、文字列を作成していて、js インタープリターはそれを html タグではなく文字列として処理するため、js はその文字列に表示されるスクリプト タグをあまり気にしません。

もちろん、 eval - は悪であるため、 eval() の使用を開始すると機能します:))

結局のところ、スクリプト タグを動的に作成して、コードで埋めることができます。

var elem = document.getElementById("dynamicDiv"),
    scriptTag = document.createElement('script'),
    scriptTagCode = 'function hello (val){alert("hello " + val);}';

scriptTag.innerHTML = scriptTagCode;
elem.appendChild(scriptTag);
hello('foo');
于 2013-03-22T10:20:38.917 に答える