0

textareaユーザーが HTML を入力し、それが body 要素に出力されるボックスがありますiframe

これは、ほとんどの HTML タグを使用して問題なく機能しますが、<script>(JavaScript を追加するために) タグを使用すると、script要素はiframe.

たとえば、 に次のように入力できるはずですtextarea

<script>
    function test() {
        alert('test');
    }
</script>
<button onclick="test()">test</button>

ボタンは に追加されますがiframescript要素は明らかに追加されていないため、ボタンをクリックしても は起動しませんalert()

これに対する 1 つの回避alert()策は、事前にスクリプト化された関数を使用するのではなく、ボタンのクリック時に宣言することです。この回避策を以下に示します。

<button onclick="alert('test')">test</button>

ただし、これは 1 つの JavaScript コマンドのみを許可します (ユーザーは複数のコマンドで関数を使用したい場合があります)。

ここでウェブページを見ることができます

iframe コンテンツを埋める JavaScript は次のとおりです。

(function () {
    $('.grid').height($(window).height());
    var frame = $('iframe'),
        contents = frame.contents(),
        body = contents.find('body'),
        styleTag = contents.find('head')
            .append('<style></style>')
            .children('style');
    $('textarea').focus(function () {
        var $this = $(this);
        $this.keyup(function () {
            if ($this.attr('id') === 'html') {
                body.html($this.val());
            } else {
                styleTag.text($this.val());
            }
        });
    });
})();
4

1 に答える 1

1

問題は、「ユーザーが生成した」スクリプトが親ウィンドウのグローバル コンテキスト (iframe が [通常] アクセスできない) で実行されることです。ボタンをクリックすると、コンソールに次のエラーが表示されます。これは、test()関数が iframe のスコープごとにアクセスできないためです。

Uncaught ReferenceError: テストが定義されていません

iframeこれを修正するには、スクリプトでの内部ウィンドウのグローバル スコープに関数を追加する必要があります。

<script>
(function () {
    'use strict';
    var iframe = document.getElementById('iframe'), //grab the iframe
        win = iframe.contentWindow; //get the window of the iframe
    win.test = function () { //declare function in scope of iframe's window
        alert('test'); //now "test" will fire because it's defined in a scope accessible to the iframe
    };
}());
</script>
<button onclick="test()">test</button>
于 2013-07-01T01:52:15.550 に答える