Invoking JavaScript code in an iframe from the parent page

后端 未结 17 1824
栀梦
栀梦 2020-11-21 07:00

Basically, I have an iframe embedded in a page and the iframe has some JavaScript routines I need to invoke from the parent page.

Now the o

相关标签:
17条回答
  • 2020-11-21 07:02

    I found quite an elegant solution.

    As you said, it's fairly easy to execute code located on the parent document. And that's the base of my code, do to just the opposite.

    When my iframe loads, I call a function located on the parent document, passing as an argument a reference to a local function, located in the iframe's document. The parent document now has a direct access to the iframe's function thru this reference.

    Example:

    On the parent:

    function tunnel(fn) {
        fn();
    }
    

    On the iframe:

    var myFunction = function() {
        alert("This work!");
    }
    
    parent.tunnel(myFunction);
    

    When the iframe loads, it will call parent.tunnel(YourFunctionReference), which will execute the function received in parameter.

    That simple, without having to deal with the all the non-standards methods from the various browsers.

    0 讨论(0)
  • 2020-11-21 07:04

    Try just parent.myfunction()

    0 讨论(0)
  • 2020-11-21 07:07

    If the iFrame's target and the containing document are on a different domain, the methods previously posted might not work, but there is a solution:

    For example, if document A contains an iframe element that contains document B, and script in document A calls postMessage() on the Window object of document B, then a message event will be fired on that object, marked as originating from the Window of document A. The script in document A might look like:

    var o = document.getElementsByTagName('iframe')[0];
    o.contentWindow.postMessage('Hello world', 'http://b.example.org/');
    

    To register an event handler for incoming events, the script would use addEventListener() (or similar mechanisms). For example, the script in document B might look like:

    window.addEventListener('message', receiver, false);
    function receiver(e) {
      if (e.origin == 'http://example.com') {
        if (e.data == 'Hello world') {
          e.source.postMessage('Hello', e.origin);
        } else {
          alert(e.data);
        }
      }
    }
    

    This script first checks the domain is the expected domain, and then looks at the message, which it either displays to the user, or responds to by sending a message back to the document which sent the message in the first place.

    via http://dev.w3.org/html5/postmsg/#web-messaging

    0 讨论(0)
  • 2020-11-21 07:10

    Assume your iFrame's id is "targetFrame" and the function you want to call is targetFunction():

    document.getElementById('targetFrame').contentWindow.targetFunction();
    

    You can also access the frame using window.frames instead of document.getElementById.

    // this option does not work in most of latest versions of chrome and Firefox
    window.frames[0].frameElement.contentWindow.targetFunction(); 
    
    0 讨论(0)
  • 2020-11-21 07:10

    Quirksmode had a post on this.

    Since the page is now broken, and only accessible via archive.org, I reproduced it here:

    IFrames

    On this page I give a short overview of accessing iframes from the page they’re on. Not surprisingly, there are some browser considerations.

    An iframe is an inline frame, a frame that, while containing a completely separate page with its own URL, is nonetheless placed inside another HTML page. This gives very nice possibilities in web design. The problem is to access the iframe, for instance to load a new page into it. This page explains how to do it.

    Frame or object?

    The fundamental question is whether the iframe is seen as a frame or as an object.

    • As explained on the Introduction to frames pages, if you use frames the browser creates a frame hierarchy for you (top.frames[1].frames[2] and such). Does the iframe fit into this frame hierarchy?
    • Or does the browser see an iframe as just another object, an object that happens to have a src property? In that case we have to use a standard DOM call (like document.getElementById('theiframe')) to access it. In general browsers allow both views on 'real' (hard-coded) iframes, but generated iframes cannot be accessed as frames.

    NAME attribute

    The most important rule is to give any iframe you create a name attribute, even if you also use an id.

    <iframe src="iframe_page1.html"
        id="testiframe"
        name="testiframe"></iframe>
    

    Most browsers need the name attribute to make the iframe part of the frame hierarchy. Some browsers (notably Mozilla) need the id to make the iframe accessible as an object. By assigning both attributes to the iframe you keep your options open. But name is far more important than id.

    Access

    Either you access the iframe as an object and change its src or you access the iframe as a frame and change its location.href.

    document.getElementById('iframe_id').src = 'newpage.html'; frames['iframe_name'].location.href = 'newpage.html'; The frame syntax is slightly preferable because Opera 6 supports it but not the object syntax.

    Accessing the iframe

    So for a complete cross–browser experience you should give the iframe a name and use the

    frames['testiframe'].location.href
    

    syntax. As far as I know this always works.

    Accessing the document

    Accessing the document inside the iframe is quite simple, provided you use the name attribute. To count the number of links in the document in the iframe, do frames['testiframe'].document.links.length.

    Generated iframes

    When you generate an iframe through the W3C DOM the iframe is not immediately entered into the frames array, though, and the frames['testiframe'].location.href syntax will not work right away. The browser needs a little time before the iframe turns up in the array, time during which no script may run.

    The document.getElementById('testiframe').src syntax works fine in all circumstances.

    The target attribute of a link doesn't work either with generated iframes, except in Opera, even though I gave my generated iframe both a name and an id.

    The lack of target support means that you must use JavaScript to change the content of a generated iframe, but since you need JavaScript anyway to generate it in the first place, I don't see this as much of a problem.

    Text size in iframes

    A curious Explorer 6 only bug:

    When you change the text size through the View menu, text sizes in iframes are correctly changed. However, this browser does not change the line breaks in the original text, so that part of the text may become invisible, or line breaks may occur while the line could still hold another word.

    0 讨论(0)
  • 2020-11-21 07:11

    Folowing Nitin Bansal's answer

    and for even more robustness:

    function getIframeWindow(iframe_object) {
      var doc;
    
      if (iframe_object.contentWindow) {
        return iframe_object.contentWindow;
      }
    
      if (iframe_object.window) {
        return iframe_object.window;
      } 
    
      if (!doc && iframe_object.contentDocument) {
        doc = iframe_object.contentDocument;
      } 
    
      if (!doc && iframe_object.document) {
        doc = iframe_object.document;
      }
    
      if (doc && doc.defaultView) {
       return doc.defaultView;
      }
    
      if (doc && doc.parentWindow) {
        return doc.parentWindow;
      }
    
      return undefined;
    }
    

    and

    ...
    var el = document.getElementById('targetFrame');
    
    var frame_win = getIframeWindow(el);
    
    if (frame_win) {
      frame_win.targetFunction();
      ...
    }
    ...
    
    0 讨论(0)
提交回复
热议问题