Reputation: 96
So I am making a JS playground like JSFiddle. While adding the JavaScript functionality and calling different functions, it seems like the code is running from the page document root and not the iframe one.
$(document).ready(function()
{
var result = $("#result");
htmlVal = htmlEditor.getValue();
cssVal = cssEditor.getValue();
jsVal = jsEditor.getValue();
iframe = $("<iframe></iframe>");
result.append(iframe);
var iframeDoc = $(iframe.get(0).contentDocument) //iframe.contents();
bodyFrame = iframeDoc.find("body");
headFrame = iframeDoc.find("head");
cssFiddle = headFrame.append("<style id='cssEdit'>" + settings.JS + "\n" + cssVal + "</style>").children("#cssEdit");
jsFiddle = bodyFrame.append("<script id='jsEdit'>" + settings.JS + "\n" + jsVal + "</script>").children("#jsEdit");
$("#update").click(updateResult);
//setInterval(updateResult, 100);
});
function updateResult()
{
htmlVal = htmlEditor.getValue();
cssVal = cssEditor.getValue();
jsVal = jsEditor.getValue();
if(htmlVal.split("</body>").length == 2)
{
var bodyText = htmlVal.split("<body>")[1].split("</body>")[0];
bodyFrame.html(bodyText);
jsFiddle = bodyFrame.append("<script id='jsEdit'>" + settings.JS + "\n" + jsVal + "</script>").children("#jsEdit");
}
if(htmlVal.split("</head>").length == 2)
{
var headText = htmlVal.split("<head>")[1].split("</head>")[0];
headFrame.html(headText);
css = headFrame.append("<style id='cssEdit'>" + settings.JS + "\n" + cssVal + "</style>").children("#cssEdit");
} else
{
bodyFrame.html(htmlVal);
js = bodyFrame.append("<script id='jsEdit'>" + settings.JS + "\n" + jsVal + "</script>").children("#jsEdit");
}
jsFiddle.html(settings.JS + "\n" + jsVal);
cssFiddle.html(settings.CSS + "\n" + cssVal);
}
Upvotes: 0
Views: 217
Reputation: 96
So the reason of the code being executed in global namespace is because of jQuery. Calling bodyFrame.append('script'), runs document.createElement('script'), meaning the code will run in document, not in iframeDoc in my case. So we need to use pure javascript.
jsFiddle = doc.createElement("script");
jsFiddle.setAttribute("type", "text/javascript");
jsFiddle.textContent = "console.log(document.body)";
bodyFrame[0].appendChild(jsFiddle);
Upvotes: 1
Reputation: 8065
To access an iframe's document do this:
var iframeDoc = $(iframe.get(0).contentDocument)
Then you can do:
bodyFrame = iframeDoc.find("body");
headFrame = iframeDoc.find("head");
Because an iframe has it's own document root you have to search for the iframe's html from that document root.
EDIT
So a/the issue is that changing the innerHTML of a script tag doesn't run new JS. So I would recommend either using jQuery's .replaceWith()
method (http://api.jquery.com/replacewith/#replaceWith-newContent) or wrapping the embedded JS in a div
or something and changing that element's HTML
Upvotes: 0