0

I'm trying to load a zoom.it script dynamically, but I can't seem to do so without document.write. The problem with document.write is that it replaces everything on my page, which I don't want. What other alternatives are there?

This is document.write in action: http://jsfiddle.net/JyT9B/6/ (notice the element that gets removed).

Also, putting the <script> tag straight into the body works: http://jsfiddle.net/gTcRw/5/, but I need it to be dynamically placed.


I've also tried the methods in Ways to add javascript files dynamically in a page, and How to add and remove js files dynamically, but seem to get the error Cannot set property 'innerHTML' of null, which is probably a zoom.it specific thing. I wouldn't mind knowing why this is the case.

The jsfiddle examples of using the other approaches:

Also tried this in vain: .innerHTML - it gets added to the dom but isn't run.

Community
  • 1
  • 1
zlog
  • 3,286
  • 3
  • 39
  • 78
  • Yes, you would need to execute `document.write` before DOMready (http://jsfiddle.net/JyT9B/7/) - but that's not dynamic either – Bergi Oct 29 '12 at 23:30
  • Do they have a non-minified version of their script, so we could debug why that `P` is `null` when loaded dynamically? – Bergi Oct 29 '12 at 23:32
  • @Bergi, Thanks for the tip about `document.write`. That could be useful. Also, nope, I haven't got access to the non-minified version. – zlog Oct 29 '12 at 23:40

2 Answers2

2

I think the combination of createElement and appendChild should work, in something like this:

http://jsfiddle.net/kbDny/3/

$(function() {
    getScript("http://www.zoom.it/aaa.js");
});

function getScript(src) {
    var scr = document.createElement("script");
    scr.type = "text/javascript";
    scr.src = src;

    var head = document.getElementsByTagName("head")[0];
    head.appendChild(scr);
}

But there's no reason to not use $.getScript - just pass the url as the first argument, like:

$.getScript(url, function (data, textStatus, jqxhr) {
    // Script loaded successfully
});
Ian
  • 46,701
  • 13
  • 94
  • 107
  • 1
    He already does that (["*document.createElement in a function*"](http://jsfiddle.net/demC4/4/)), but it throws the exception too – Bergi Oct 29 '12 at 23:34
  • @Bergi I don't why I didn't check the links - I thought they were explanations of how to use it...I just wanted to provide an example. Anyways, the "exception" thrown is from the script that is loaded, not the code...so we have no control over that - the loading works. – Ian Oct 29 '12 at 23:40
  • I think he knows how to dynamially add scripts (he linked a question on that), he rather wants to know why this particular script does not work when dynamically inserted – Bergi Oct 29 '12 at 23:46
  • @Bergi So yeah, that's what I meant in my last comment. I didn't realize that when I read the question - I thought the OP was providing links for the methods (without applying to their specific code) and that's why i didn't read them and know that...and posted a redundant answer. – Ian Oct 29 '12 at 23:49
1

Ended up using an iframe to contain a html page with an embedded script tag.

The benefit of an iframe is that I can show/remove it at will, without having to worry about cleaning up the current page document when removing the script.

ie,

HTML

<body>
  <div id="container">
    <a id="show" href="#">show</a>
    <a id="close" href="#">close</a>

    <div id="placeholder"></div>
  </div>
</body>​

JavaScript

function appendFrame(elem) {
  var iframe = document.createElement("iframe");
  iframe.id = "iframe";
  iframe.setAttribute("src", "about:blank");
  iframe.style.width = "200px";
  iframe.style.height = "200px";
  $(elem).append(iframe);
}

function loadIFrame() {
  appendFrame($("#placeholder"));

  var doc = document.getElementById('iframe').contentWindow.document;
  doc.open();
  doc.write("<html><head><title></title></head><body><script src='http://zoom.it/aaa.js'><\/script><\/body><\/html>");
  doc.close();
};

$("#show").click(function() {
  loadIFrame();
});

$("#close").click(function() {
  $("#iframe").remove();
});​

JSFiddle solution here: http://jsfiddle.net/7KRcG/2/

zlog
  • 3,286
  • 3
  • 39
  • 78
  • 1
    -1 because it's invalid HTML to have an iFrame inside a [script element](http://dev.w3.org/html5/spec/single-page.html#the-script-element). You are depending on browser quirks and error correction, which is a very bad strategy. Further, script elements don't have an innerHTML property, they do have [*textContent*](http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1950641247) and [*text*](http://dev.w3.org/html5/spec/single-page.html#the-script-element) properties. – RobG Oct 30 '12 at 00:53
  • 1
    +1 Even correct quoting of closing tag characters in the `document.write` part. And `document.close()`. Damn. :-) – RobG Oct 30 '12 at 23:28