4

I have a html document loaded in an iframe.
I have developed some popup-menu code in javascript for that document and I inject the code into the iframe from the main document.

But my code does not work in the iframe because it uses the "document" object and that surprisingly refers to the main document and not the iframe document.

I also play around content selection and there I need window.getSelection() which goes back to the main document's selections and I'd need window.frames[0].getSelection() instead.

Am I doing sth wrong?
Is there any simple solution to overcome this?

UPDATE:(clarification)
As Bergi pointed out, my question is about how to run correctly injected javascript code to get local scope and not global scope in the iframe?
So I do not have to rewrite document's and window's in the code...

UPDATE: (skeleton of my html)

<html>
  <head></head> <!-- script launches on jquery's $(document).ready -->
  <body>
    <iframe>
    [
      <body>
        ...
        <script></script> <!-- code injected here from the code (appended to the body) -->
      </body>
    ]
    </iframe>
  </body>
</html>

The script goes like this (using jquery):

$(function(){
$('iframe').load(function(){

var $doc = $('iframe').contents();
var $head = $('head', $doc);
$head.append('<link rel="stylesheet" href="/stylesheets/book-popup-menu.css" />');

var $body = $('body', $doc);
$body.append(' \
    <div id="popup"> \
    </div> \
');
$body.append(' \
    <script type="text/javascript"> \
              console.log(document.body);// it still displays the global body \
            </script> \
');
});
});

UPDATE: A fiddle demonstrating the issue

6
  • Depends on how you inject the code into the iframe - show us that snippet, please. If you're doing it wrong, the code is still executed in the global scope of the parent document. Commented May 7, 2013 at 14:40
  • @Bergi Thanks, I've updated my question as you asked. Commented May 7, 2013 at 15:19
  • And you say that the /scripts/book-popup-menu.js is executed with document pointing to the parent frame's one? Commented May 7, 2013 at 15:26
  • yes, exactly. What am I doing wrong? Commented May 7, 2013 at 16:08
  • I have no idea what's going on yet, but I can confirm the problem. Commented May 7, 2013 at 16:46

1 Answer 1

2

Finally, I've found an answer!

If you append code with jQuery like $body.append('<script>') then the '' element gets created by document.createElement('script') thus will be part of the global document. Even after it is inserted to the iframe document, it will execute in the global namespace.

So the solution is -- taking advantage of this fabulous solution:(Injecting Javascript to Iframe) -- to fall back to vanilla javascript:

$('iframe').load(function(){

    var $doc = $('iframe').contents();
    var $head = $('head', $doc);
    $head.append('<link rel="stylesheet" href="/stylesheets/book-popup-menu.css" />');

    var $body = $('body', $doc);
    $body.append('<div id="popup"></div>');// non-javascript content works fine

    var doc = $('iframe').contents()[0]; // doc = $doc[0] does not work for some reason... 

    var script = doc.createElement("script");
    script.setAttribute("type", "text/javascript");
    script.textContent = "console.log(document.body)"; // this will be iframe's body
    $body[0].appendChild(script1); // $body.append(...) does not work
});
Sign up to request clarification or add additional context in comments.

1 Comment

I think you could as well use something like $("#popup", $doc).html("<script>…"), that should not create an element in jQuery's context.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.