他のページ(ウィンドウ)へのアクセス

最近、掲示板などで他のウィンドウへのアクセスに関する質問をよく見ます。


知っている人にとっては当たり前ですが、window.openは非同期でウィンドウを開きます。
戻り値が開いたウィンドウの参照になっていますが、ページのロードは待ちません。


var win = window.open("hoge.html");
var name = win.document.getElementById("username").value;
など、window.open直後では、開いたページのロードが完了していない可能性があります。

どうしても同期させたい場合は

  1. 子から親にアクセスする
  2. ループして子のロード完了を待つ

    var win = window.open("hoge.html");
      var timer = 5;  //sec
      var limit = (new Date()).getTime() + timer * 1000;
      while( (new Date()).getTime() < limit) {
        try {
          if(win && win.document && win.document.body && win.document.getElementById) {
            break;
          }
        } catch(e) {
        }
      }
    var name = win.document.getElementById("username").value;
    ※必ずタイムアウトを付け、ロードされたらあるはずの何かをtry〜catchの中でチェックします。
  3. 子に対するその後の処理をタイマーにする
などが考えられます。


また、あるページ内で生成したオブジェクトの実体はそのページ内にあり、別ページに渡したとしてもそれはオブジェクトの参照です。
==A.html==


var obj_a = new Date();
var win_b = window.open("B.html");
==B.html==

var obj_b = new Date();
var win_a = opener;
window.onload = function() {
  win_a.obj_b = obj_b;
};
BからAへobj_bを渡し終わった後、A.htmlで実験してみます。

alert(obj_a.constructor == Date);  // true
alert(obj_b.constructor == Date);  // false
alert(obj_b.constructor == win_b.Date);  // true
alert(obj_b.toLocaleString());

win_b.close();

alert(obj_b.toLocaleString());  // エラー

このように、オブジェクトの実体を渡すことはできません。
(プリミティブ型は値渡しなので、問題なく他ページに渡すことができます。)


それと、ドメインプロトコル含む)の違うページには、たとえ自分が開いたとしてもアクセスできません。
通常のブラウザの設定ではそうなっていますし、アクセスできたらセキュリティ上問題があります。

ただし、一部のブラウザでは(おそらくその仕様の範囲内で)他のドメインのページに動的にデータを渡すことができます。
1つのウィンドウ内に複数フレームがあり、フレームの各ページが同じドメインでないとしても、statusの値は共有されています。
(別ウィンドウ:×,別タブ:たぶん○)

つまり、あるドメインスクリプトがstatusに何か書き込み、それを別ドメインスクリプトが読み込む・・・そのような作りが可能です。
文字列型しか渡せませんから、通信をするページ間で何か決まりごとを作る必要があります。