user2536988
user2536988

Reputation: 31

JavaScript not being inputted into iframe

I have a textarea box where the user inputs HTML and it gets output into the body element of an iframe.

This works just fine using most HTML tags, but if you use the <script> tag (in order to add JavaScript), the script element does not get transferred to the iframe.

For example, I should be able type the following in the textarea:

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

The button gets added to the iframe but since the script element apparently doesn't, clicking the button does not fire the alert().

One work-around for this is to declare alert() on the button click, rather than using a pre-scripted function; this work-around is shown below:

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

However this only allows one javascript command (whereas the user may want to use a function with multiple commands).

You can see the webpage here

The JavaScript to fill the iframe contents is:

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

Upvotes: 0

Views: 133

Answers (1)

pete
pete

Reputation: 25081

The problem is any "user-generated" scripts will be executed in the parent window's global context (which the iframe cannot [normally] access). The console shows the following error when clicking the button because the test() function is not accessible scope-wise for the iframe:

Uncaught ReferenceError: test is not defined

To fix this, scripts need to add functions to the global scope of the iframe's internal window:

<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>

Upvotes: 1

Related Questions