Clean the cache of iframe - javascript

I have an erroneous html+javascript. It returns a Uncaught ReferenceError: number is not defined, which is expected:
<!DOCTYPE html>
<meta name="robots" content="noindex">
<html>
<body>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = number();
</script>
<script id="jsbin-javascript">
function number() {
return 1;
}
</script>
</body>
</html>
However, if I run the code as a string by iframe twice (plnkr), the second run oddly returns a result. It is because the number function is cached somewhere by the first run, which is not what I want.
<!DOCTYPE html>
<html>
<head>
<script src="script.js"></script>
</head>
<body>
<iframe></iframe>
<script>
var iframe = document.querySelector('iframe');
var iframe_doc = iframe.contentDocument;
iframe_doc.open();
iframe_doc.write(source);
iframe_doc.close();
var iframe = document.querySelector('iframe');
var iframe_doc = iframe.contentDocument;
iframe_doc.open();
iframe_doc.write(source);
iframe_doc.close();
</script>
</body>
</html>
So does anyone know how to clean the cache, such that each run of iframe is completely a new one?
Edit 1 Following the answer of #LeonidVasilyev, I have added in html:
<section id="output">
<iframe></iframe>
</section>
And in JavaScript of my playground:
this.render = function (code) {
var source = prepareSource(code);
var placeholder = document.getElementById("output");
while (placeholder.firstChild) {
placeholder.removeChild(placeholder.firstChild);
}
var iframe = document.createElement("iframe");
placeholder.appendChild(iframe);
var iframe_doc = iframe.contentDocument;
iframe_doc.open();
iframe_doc.write(source);
iframe_doc.close();
}
What is odd is that, every time I reload/refresh the page, the paper icon in the Chrome tab and the reload round icon each flash twice. It is because of placeholder.appendChild(iframe), because if i remove this line, it flashes once.
Does anyone know how to avoid this icon twice-flashing?

That is a Chrome bug. In your case document.open() must create new global object. Excerpt from description of document.open() algorithm in HTML specification:
Call the JavaScript InitializeHostDefinedRealm() abstract operation with the following customizations:
For the global object, create a new Window object window.
For the global this value, use the current browsing context's
associated WindowProxy.
Let realm execution context be the created JavaScript execution
context.
Firefox 51 and Internet Explorer 11 properly create new Window object.
As a workaround you can create new iframe node on each iteration:
<!DOCTYPE html>
<html>
<head>
<script src="script.js"></script>
</head>
<body>
<div id="placeholder"></div>
<script>
var placeholder = document.getElementById("placeholder");
var iframe = null;
iframe = document.createElement("iframe");
placeholder.appendChild(iframe);
var iframe_doc = iframe.contentDocument;
iframe_doc.open();
iframe_doc.write(source);
iframe_doc.close();
iframe = document.createElement("iframe");
placeholder.appendChild(iframe);
var iframe_doc = iframe.contentDocument;
iframe_doc.open();
iframe_doc.write(source);
iframe_doc.close();
</script>
</body>
</html>

Related

Open a new window from the apps script add-on menu

I have an add-on where I need to redirect to external URL instead loading with Dialog or Sidebar when the menu is clicked.
I have the sidebar code
function showContactDialog() {
var html = HtmlService.createTemplateFromFile('Website').evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME).setWidth(480).setHeight(380);
SpreadsheetApp.getUi().showModalDialog(html, 'Website');
}
In your HTML you can open a new tab (if your browser supports such a thing) but you can't redirect the page.
In your HTML, you can do something like below:
<script>
function openPage() {
window.open('https://google.com', '_blank');
}
window.onload = openPage;
</script>
In your Website.html place this code
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script type="text/javascript">
function opentab(){
window.open(LINK_YOU_WANT_TO_OPEN, '_blank');
}
</script>
</head>
<body onload="opentab()">
</body>
</html>
This works fine for me
function open_new_doc()
{
var html = '<script>google.script.host.close();'+
'window.location.href = "'+open_url+'"</script>';
var html_open = HtmlService.createHtmlOutput(html).setSandboxMode(HtmlService.SandboxMode.IFRAME);
DocumentApp.getUi().showModalDialog(html_open, 'Opening New Window...');
}

How to get a reference to an object created on an iframe from the main frame

I have an iframe and I need to use that iframe to create a new object from a script running in the main frame. The problem is, when I instantiate an object in this way, it gives back undefined, so I do not have a way to get the reference and manipulate the object.
The example shows what is going on:
//main.html
<html>
<script>
var iframe = document.getElementsByTagName("iframe")[0];
//it gives back undef instead of the new object
var foo = new iframe.contentWindow.Foo();
</script>
<iframe src="second.html"></iframe>
</html>
//second.html
<html>
<script>
window.Foo = function() {
this.bar = "BAR";
}
</script>
</html>
I know that this is caused, because the execution environment differs for the main frame and the iframe, but is there any way to get a reference for the object created on the iframe?
I tried to put the variable to the iframe's global scope, hoping that it works, but it is still undefined:
//main.html
<html>
<script>
var iframe = document.getElementsByTagName("iframe")[0];
//I hoped this helps (because now the variable is on the same
//global environment), but still undefined
iframe.contentWindow.foo = new iframe.contentWindow.Foo();
</script>
<iframe src="second.html"></iframe>
</html>
//second.html
<html>
<script>
window.Foo = function() {
this.bar = "BAR";
}
</script>
</html>
On the main page yoou define the name of your page:
<head>
<script>
window.name = "home";
var home = window;
var NS_MAIN = {
init:function(){
alert(home.SECOND.globalVal);
}
};
</script>
</head>
<body>
<iframe id="frame" src="secondPage.html" border="1" width="50%" height="50%"></iframe>
your secondPage
<head>
<script>
var NS_SECOND = {
globalVal:null,
init:function(){
home.SECOND= this;
NS_SECOND.globalVal="Hello";
}
};
</script>
</head>
<body>
</body>

IE unknown runtime error while setting innerhtml

I am trying to set style inside head tag dynamically inside a iframe so as to set the class
on body of the iframe while loading of the iframe itself, say I want to apply the ze_edit
class on the body of iframe like this ::---
<head>
<style type="text/css">
.ze_edit{font-family:Verdana,arial,Helvetica,sans-serif;font-size:12px;}
</style>
</head>
<body class = "ze_edit">
</body>
Below is the full code of the sample test file.
<html>
<head>
<script>
test = function()
{
var _style,
_iframe,
_doc,
_head,
ff,
fs;
ff = "georgia,times new roman,times,serif";
fs = "30pt"
_doc = document;
_iframe = _doc.getElementsByTagName("iframe")[0];
_iframe.contentWindow.document.designMode="on";
_style = _doc.createElement("style");
_style.type = "text/css";
_style.innerHTML = ".eclass{font-family:"+ff+";font-size:"+fs+"}";
_head = _iframe.contentWindow.document.getElementsByTagName("head")[0];
_head.appendChild(_style);
_iframe.contentWindow.document.body.className = "eclass";
}
</script>
</head>
<body>
This is a just a test
<iframe onload ="test()">
satyam
</iframe>
</body>
</html>
But this script throws error "Unknown runtime error" at this line
"*_style.innerHTML = ".eclass{font-family:"+ff+";font-size:"+fs+"}*";
" in IE .
Any workaround solution for this..
This could be some IE bug/feautre. Do it like in this post:
How to change/remove CSS classes definitions at runtime?

Scripts do not execute when changing the content of an iframe with innerHTML

I would like to load the content of an iframe with JavaScript. I don't want to change the src but directly the content with:
document.getElementById('frame').contentDocument.body.innerHTML = data;
It works but the JavaScript in data is not executed. Is it a security protection or I forgot something?
It looks like the problem is not the iframe, but the fact that scripts are not executed when inserted into the DOM text with innerHTML.
You may want to check the following Stack Overflow post for a couple of solutions:
Can scripts be inserted with innerHTML?
Use this for getting the document crossbrowser
//returns iframe document
function getIFrameDocument(iframe) {
var doc;
if (iframe.contentDocument) {//FF-Chrome
doc = iframe.contentDocument;
} else if (iframe.contentWindow) {
doc = iframe.contentWindow.document;
} else if (iframe.document) {//IE8
doc = iframe.document;
} else {
doc = window.frames[iframe.id].document;
}
return doc;
}
Try this
in a page index.html write:
<script type="text/javascript">
function init()
{
var s = document.createElement("script");
s.innerHTML="alert('ops');"
document.getElementById("frame").contentDocument.getElementsByTagName("body")[0].appendChild(s);
}
window.onload = init;
</script>
...
<body>
<form id="form1">
<div>
<iframe id="frame" src="test.html"></iframe>
</div>
</form>
</body>
Then simply write test.html like:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
</body>
</html>
and load from a web server index.html and the code works!!
Having something like the following would work.
<iframe id = "testframe" onload = populateIframe(this.id);></iframe>
// The following function should be inside a script tag
function populateIframe(id) {
var text = "This is a Test"
var iframe = getObj(id);
var doc;
if(iframe.contentDocument) {
doc = iframe.contentDocument;
} else {
doc = iframe.contentWindow.document;
}
doc.body.innerHTML = text;
}

call function on iframe mouse move

I have a function that i need to call on iframe mousemove(). But i didnt found anything like we have in body tag
We have <body mousemove="Function()"> Do we have anything like this for iframe??
The iframe contains its own document, own body element etc.
Try something like this:
var frame = document.getElementById("yourIframeId");
// IE is special
var frameDoc = frame.contentDocument || frame.contentWindow.document;
var frameBody = frameDoc.getElementsByTagName("body")[0];
var testingOneTwo = function() {
console.log("Hello, is this thing on?");
};
frameBody.onmouseover = testingOneTwo;
Did you mean onMouseOver or onFocus?
e.g.
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<script language="javascript">
<!--
function SayHello()
{
alert("Hi from IFrame");
}
//-->
</script>
</HEAD>
<BODY>
<iframe id="myiFrame" onMouseOver="SayHello()"/>
<iframe id="myiFrame" onFocus="SayHello()"/>
</BODY>
</HTML>

Categories