4

I have the following code to execute JavaScript in an iframe (in this case frames[0], since the app contains only 1 iframe at any given time):

Following works if js contains core/pure JavaScript:

var js = ""; // JavaScript code here
frames[0].window.eval(js);  

But it does not work if 'js' contains jQuery:

var js = ""; // JavaScript or jQuery code here
var preview = document.createElement('iframe_id');  
preview.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ;
document.body.appendChild(preview); 
frames[0].window.eval(js);  

Is there any alternative to window.eval() in jQuery? I know .globalEval() is there, but it seems to be for a different purpose.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
Gandalf
  • 920
  • 3
  • 10
  • 24

5 Answers5

1

This is because jQuery didn't load yet, you could attach a onload or check onreadystatechanged on the iframe to figure out when it has loaded.

hank
  • 3,748
  • 1
  • 24
  • 37
1

You have to make sure jQuery script is loaded before you try to eval code that uses jQuery syntax. Take a look at this thread https://stackoverflow.com/a/6725358/937367.

function scriptTag(src, callback) {

    var s = document.createElement('script');
    s.type = 'text/' + (src.type || 'javascript');
    s.src = src.src || src;
    s.async = false;

    s.onreadystatechange = s.onload = function() {

        var state = s.readyState;

        if (!callback.done && (!state || /loaded|complete/.test(state))) {
            callback.done = true;
            callback();
        }
    };

    // use body if available. more safe in IE
    (document.body || head).appendChild(s);
}

Eval your code in callback function like below and all should be fine.

var js = ""; // JavaScript or jQuery code here
scriptTag("http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js", function(){
    frames[0].window.eval(js); 
});

I tested it here http://jsfiddle.net/SFUbg/2/. I don't know why in that scriptTag function doc was used instead of document, as this is no equivalent, so I changed it.

Community
  • 1
  • 1
Jan.J
  • 3,050
  • 1
  • 23
  • 33
1

The reason could be your iframe does not load jquery library. Try:

var js = ""; // JavaScript or jQuery code here
var preview = document.createElement('script');  
preview.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ;
frames[0].window.document.body.appendChild(preview); 
frames[0].window.eval(js);  
  • document.createElement('script'); instead of document.createElement('iframe_id');
  • Execute this line frames[0].window.document.body.appendChild(preview); to load jquery for your iframe.
Khanh TO
  • 48,509
  • 13
  • 99
  • 115
0

jQuery is not a separate language. At least one reason your code will not work is that createElement takes a tag name, which 'iframe_id' is not.

Also, you are setting the src of the iframe directly to jQuery. You should be setting it to an HTML page, or about:blank, then somehow loading jQuery. The easiest way to load it is simply to set the iframe URL to a HTML page with an explicit loading jQuery.

EDIT: If the iframe already exists and is loaded, and you just want to add jQuery to it, Jan.J's answer should help.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
0

Here's code we're using quite successfully in a project that uses multiple iframes, adapted to your what you're seemingly doing:

function setContent(source) {
  var iframe = document.createElement("iframe");
  iframe.style.opacity = 0.0;   
  document.body.appendChild(iframe);

      // set new content
  doc = iframe.contentDocument;
  doc.open();
  doc.write(sourceCode);
  doc.close();

  // kill off old iframe
  document.body.removeChild(document.querySelector("iframe"));
  iframe.style.opacity = 1.0;

  // inject the script you needed
  var scriptElement = doc.createElement("script");
  scriptElement.src = "...";
  doc.querySelector("head").appendChild(scriptElement);
}

And have a http://jsbin.com/iFoZAdU/8/edit for the working code.

Now never post five identical questions again please.

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153