Lesson 0002 · ~10 minutes

How you get a handle

One skill: name the WindowProxy for the window you want. Then you can send data with postMessage.

Win for this lesson

You can say this: “The iframe element is not the handle. contentWindow is the handle. Inside a child I use parent or top. In a popup I use opener.”

1. The problem

You cannot send data to a window if you do not hold it.

A WindowProxy is that hold.

You get a WindowProxy in a small set of ways.

This lesson teaches those ways. It does not add new postMessage rules.

2. Four ways

You want You write
The window inside an iframe element iframe.contentWindow
The page that embeds this page window.parent
The outermost page window.top
The page that opened this popup window.opener

window.open(...) returns the WindowProxy of the new window (MDN). Store that value.

event.source is also a WindowProxy. That is the next lesson.

3. parent and top

If this page is not in an iframe, parent is this window. top is this window. (MDN parent)

If this page is in one iframe, parent and top are the same handle.

If this page is in a nested iframe, they are not the same handle.

this page          parent === this window
                   top    === this window
    |
    |  iframe.contentWindow
    v
mid iframe         parent === this page
                   top    === this page
    |
    |  iframe.contentWindow
    v
inner iframe       parent === mid
                   top    === this page

From inner, parent is mid. top is this page.

Pick parent when you want the embedder.

Pick top when you want the outermost page.

4. opener

window.open makes a new window. The return value is the handle of that window.

Inside the new window, opener is the page that called open (MDN).

opener is not parent.

A popup is not inside an iframe. Its parent is itself.

If you pass noopener, open returns null. The new window has no opener. You have no handle. (MDN)

If the popup is closed, you can still hold the handle. handle.closed is true.

React, same rule
const iframeRef = useRef(null);

function sendFilter(q) {
  const otherWindow = iframeRef.current.contentWindow;
  otherWindow.postMessage(
    { type: "set-filter", q },
    "https://widget.example",
  );
}

return <iframe ref={iframeRef} src="https://widget.example" />;

The ref is the iframe element. contentWindow is the WindowProxy.

5. Do these steps

The box below has a real mid iframe. Mid has a real inner iframe.

  1. Read the tree. This page: parent===self true, top===self true.
  2. Read Mid and Inner. Inner: parent===self false, parent===top false.
  3. Click Read mid title. The code uses iframe.contentWindow.
  4. Click Read inner title. The code uses mid.frames[0]. That is the inner WindowProxy.
  5. Click Open popup. The popup row must say opener is null: false. Close the popup. Click Is popup closed?

Optional: click Open with noopener. The call must return null. You have no handle.

6. Practice

Do the five steps first. Then answer these questions.

Question A

You have an iframe element. You need the child's WindowProxy.

Question B

You are inside a nested iframe. You need the page that embeds you.

Question C

You are in the innermost iframe. You need the outermost page.

Question D

You are in a popup. You need the page that opened you.

Question E

You are not in an iframe. You read window.parent.

7. Remember

Ask your teacher If a sentence is not clear, ask. If a lab step does not match the text, ask. That is part of the method.

Primary source (read next)

MDN — Window.parent and MDN — Window.open(). Then contentWindow and opener.