4

Context:

I am building a live HTML,CSS & Javascript editor. It can be accessed here.

The source can be accessed here.

Question:

Is it possible to run javascript code injected into an iframe without repeated removal and addition of <script> tag containing the code from and to the DOM tree? Since DOM manipulation is a costly affair, I want to try and eliminate multiple DOM manipulations. Instead I want to be able to just change the textContent of the <script> tag and have it run the new code that I've inserted.

Thanks!

zeusdeux
  • 501
  • 1
  • 6
  • 14

1 Answers1

7

If you don't mind using the evil eval, you can re-evaluate most JavaScript in the iframe's window, for example

function someFunction(){                                // any function
    console.log(document.body.children);
}

someFunction();                                         // see normal output

var ifrm  = document.getElementsByTagName('iframe')[0], // your iframe
    iwind = ifrm.contentWindow;                         // the iframe's window

iwind.eval( someFunction.toString() );                  // re-evaluate function with eval from iframe
iwind.someFunction();                                   // see new output - output is in iframe's context

compare against

iwind.someFunction = someFunction;                      // set variable
iwind.someFunction();                                   // same as calling someFunction() from parent

It should work for most valid JavaScript (take into account scope), but be aware that using eval can be bad.

Community
  • 1
  • 1
Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • Yes you can use this with `iwind.eval( myScript.textContent );` too, but be aware that unless you set things you don't want any more to `null` or `undefined`, they will exist as long as the `iframe` is on the same page. This applies to removing & appending a new ` – Paul S. Oct 07 '12 at 23:09
  • is there a workaround for that? any garbage collection strategies that clean up after a ` – zeusdeux Oct 08 '12 at 08:41
  • It's not that they don't get GC'd for no reason - when script from a ` – Paul S. Oct 08 '12 at 21:28
  • Ok this is a long shot and arises from the fact that I cant seem to find any good documents on the way browsers interpret javascript, but : what if i store the reference to the `iframe` `contentWindow` in a var in the parent window, then set the `iframe` `contentWindow` to null (to probably cause a GC sweep) and then set it back using the parent window `var` and use it after the gc sweep? I am assuming that when i set the `contentWindow` of the `iframe` to null, it causes the GC to do a sweep. Thanks for the speedy replies! :) – zeusdeux Oct 11 '12 at 09:39
  • `node.contentWindow = null; node.contentWindow === null; // false`. Even if you could set it to `null`, it is an object so the variable in the parent window is _ByRef_ and it's properties would change with changes to those on `node.contentWindow`. Afaik the only way to destroy and recreate a Window object is to reload the page, hence my suggestion to compare `Object.keys(window)`. – Paul S. Oct 11 '12 at 11:03
  • that clears it all up. totally overlooked the reference aspect for some reason. Thanks! – zeusdeux Oct 11 '12 at 11:13