Reputation: 31
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
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