14

In JavaScript, let's say we have a main page (main.html) which contains an <iframe> (iframe.html).

Now inside this iframe.html, if we need to refer to something on the main page (main.html), can we not just specify window instead of parent.window.

If the answer is we need to write parent.window, I wanted to understand is there not a single window object reference for all the iframes within a main page...

While I do understand document is specific to individual iframes, but window should be common to all..Isn't it...Please help me in understanding the concept...

Also is there something window.parent as well? If yes, how does it differ from parent.window?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
copenndthagen
  • 49,230
  • 102
  • 290
  • 442

2 Answers2

13

iframes (and frames) are their own windows, even though in the case of iframes they look like they're part of the main document's window. So yes, to refer to the main document's window, they'd use parent (or window.parent if you want to be verbose, but clear), because they are separate objects. This is partially necessary because a lot of the things in document end up as properties on the containing window.

If you think about it, it makes sense: The purpose of an iframe is to embed independently-sourced content within the page. If the main page and the iframe(s) on it shared a single window object, they'd be sharing global context, and quite possibly conflicting with one another.

Gratuitous live example:

Parent's HTML:

<p>I'm the parent window</p>
<iframe width="500" height="500" src="http://jsbin.com/iyogir"></iframe>

Parent's JavaScript:

function foo() {
  display("<code>foo</code> called!");
}
function display(msg) {
  var p = document.createElement('p');
  p.innerHTML = msg;
  document.body.appendChild(p);
}

Child's HTML:

<p>I'm in the frame</p>
<input type='button' id='theButton' value='Click Me'>

Child's JavaScript:

window.onload = function() {

  document.getElementById('theButton').onclick = function() {
    var p = window.parent;
    if (!p) {
      display("Can't find parent window");
    }
    else if (typeof p.foo !== "function") {
      display("Found parent window, but can't find <code>foo</code> function on it");
    }
    else {
      display("Calling parent window's <code>foo</code> function.");
      p.foo();
    }
  };

  function display(msg) {
    var p = document.createElement('p');
    p.innerHTML = msg;
    document.body.appendChild(p);
  }

};
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
12

The concept of window is tied to the document: There's one window per document, and one document per window.

That means <iframe> elements, which have their own document, also have their own window, just like a pop-up window or the main navigator window.

So, you'll indeed have to use window.parent to access the container of an <iframe> element, just like you have to use window.opener to access the owner of a pop-up window.

EDIT: Both window.parent and parent.window are valid expressions that return the same object. That's because the window object is the default context in scripting (unqualified names are parsed as members of window), and window objects have a window property that refers to themselves.

So, parent.window is evaluated as window.parent.window, which is the same object as window.parent.

That said, I do prefer using window.parent, to avoid the (minimal) overhead associated with the extra property access.

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
  • Do I have to use window.parent to access the container OR parent.window OR both are valid? – copenndthagen Jul 13 '11 at 13:16
  • 2
    @hmthr I recommend `window.window.parent.window.window`... `:)` – Šime Vidas Jul 13 '11 at 13:28
  • @hmthr: in JavaScript on browsers, The window object is the container of all global variables. In fact, the `window` symbol is, itself, a property of the window object (referring back to the object). `parent` is also a property of the window object, and so `window.parent` is redundant, you can just say `parent`. However, it's useful for being clear about what you're doing. `parent.window` will also work, but in a misleading way: The `parent` part gives you your parent window's window object, no need to go further; and then you're looking up the `window` prop on it (which refers back to it). – T.J. Crowder Jul 13 '11 at 13:29
  • 4
    @Sime: I think you forgot a `self` somewhere in there ;) – Felix Kling Jul 13 '11 at 13:37
  • `There's one window per document, and one document per window`. If you are right, then what is `window.history`? As W3C says, `window` object is a wrapper for many documents, first of which is `about:blank` document, which would be associated with the window object on its creation. This is the concept of [`browsing context`](http://www.w3.org/TR/html5/browsers.html#windows). – Saeed Neamati Dec 08 '11 at 11:44
  • @Saeed, `window.history` refers to a `History` object that, in turn, references the documents in the session history. These documents are not directly associated with the window. The same `History` object is part of browsing contexts, and the link you provide indeed documents a special case, but the general case is a one-to-one mapping between documents and windows. – Frédéric Hamidi Dec 08 '11 at 12:06
  • From the link: `In general, there is a 1-to-1 mapping from the Window object to the Document object. In one particular case, a Window can be reused for the presentation of a second Document in the same browsing context, such that the mapping is then 2-to-1. This occurs when a browsing context is navigated from the initial about:blank Document to another, with replacement enabled.` – Frédéric Hamidi Dec 08 '11 at 12:06