45

I have a parent document with an embedded iframe. Inside the iframe I have an upload field. Once the user selects a file to upload, I trigger a jQuery change event. On that event I want to set a variable in the parent window to true, so that the parent knows that the upload has started.

Does anyone know how to do this?

Was trying this, but didn't work:

var test;
$("#newsletter_email").change(function() {
  parent.window.test = true;

});

$('#send').click(function() {
    if (test) {
        alert('File has been uploaded!');
    } else {
        alert('You need to upload a file');
    }
});
Nic Hubbard
  • 41,587
  • 63
  • 251
  • 412

2 Answers2

89

Variables in the global scope are auto-exposed as DOM properties of their containing window object.

This means that

var foo = 'bar';

is analogous to

window.foo = 'bar';

Which means that you can read the global scope of any window object you can obtain a reference to. What we can also imply here is that usage of window is implicit. Even when you don't explicitly type "window.", it's there anyway.

And since frames themselves are also auto-exposed as DOM properties of the current window object, this means you can access any other frames' window object as well.

The parent property of window objects holds a reference the window object of that window's parent (if there is one). Since iframes most certainly have a parent window, then all this stuff I just typed boils down to this

// set the global variable 'foo' in the parent global scope
parent.foo = 'bar';
Peter Bailey
  • 105,256
  • 31
  • 182
  • 206
  • Am I correct in thinking this can't be in a .js file, or the parent scope would be all screwed up? – Nic Hubbard Aug 19 '09 at 18:22
  • 4
    No. External files adopt the scope of the document into which they are included. – Peter Bailey Aug 19 '09 at 18:46
  • How does the document.ready function effect the scope of variables? I've noticed in a number of cases that often while inside document.ready variables become unavailable to functions outside. Thanks – Dan Jun 17 '12 at 13:20
  • 1
    @ErmSo - No more or less than any other function. There's only two scopes in javascript: Global and Function. So, variables scoped to a function are definitely not available in the global scope. – Peter Bailey Jun 18 '12 at 19:55
  • @makerofthings7 - no, not all functions are global. Function names are part of the symbol table just like variable names, and become scoped themselves. Writing `function foo(){}` is fundamentally no different than writing `var foo = function(){}` – Peter Bailey Apr 02 '13 at 17:40
  • 2
    I just tried this in nested iframes and discovered it works to: [code]window.top.jsVar = true //use window.top to get to the top parent form – Dan Randolph Feb 07 '14 at 18:33
  • 1
    @PeterBailey FYI you have an outdated comment here now that block scoping has come to js: [let](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/let) & [const](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/const) – Jon Surrell Oct 03 '16 at 09:02
5

You can also store it in the localStorage and read and write from it, provided that both the main document and the iframe share the same domain.

Marta
  • 388
  • 4
  • 9
  • Yeah, but not all browsers support this. – Nic Hubbard Apr 23 '13 at 17:05
  • I realize this is a bit of necroposting but it's relevant to my work now and there are a couple libraries out there (store.js and store2.js) that extend the concept of localStorage to be browser-agnostic. – HTTP 501 Sep 14 '16 at 17:08