アナログCPU:5108843109

ゲームと音楽とプログラミング(酒と女とロックンロールのノリで)

('ω') < イザユケエンジニャー

新しいウインドウを開き、そこに値を送信する

まずは結論

<HTML:親ウインドウ>

<a href="#" onclick="pushValue();">ウインドウを開いて値を送信する</a>

<HTML:子ウインドウ>

<input type="hidden" id="testid" value="">

jQuery

var obj; // 開いたウインドウを扱うためのオブジェクト変数
function pushValue(){
    // ウインドウオブジェクトが存在しない場合・閉じられている場合は新たに開く
    if (!obj || obj.closed){
        // ウインドウを開く(/childwindow.htmlを、横500px×縦500pxで)
        obj = window.open("/childwindow.html", "child", "width=500, height=500");
        
        // 書き換えたい要素が存在すれば(=書き換え部分が読み込まれれば)書き換えを行う
        // 500ミリ秒ごとにリトライ
        var timer = setInterval(function(){
            if ($("#testid", obj.document) != undefined){
                sendValue();
                clearInterval(timer);
            }
        }, 500);
    }
    // ウインドウが既に開かれている場合は要素の書き換えを行う
    else{
        sendValue();
    }
}
function sendValue(){
    $("#testid", obj.document).val("testvalue");
}

と、こんな感じでの実装となりました。
以下はjQuery部分のメイキング。

ウインドウを開く部分

「window.open(開くHTMLのパス, 名前, スタイル)」で
別ウインドウを開くことができます。

jQuery

function pushValue(){
    window.open("/childwindow.html", "child", "width=500, height=500");
}

まずはこれで開くことを確認。
ちなみに、名前(上記の例では「child」)を消すと、
リンクを押すたび新しく別のウインドウが開くようになります。

とりあえずこれだけで特に問題なく開きますが、
この後このウインドウを操作することになるので、
オブジェクト変数に入れるようにしておきます。

jQuery

var obj;
function pushValue(){
    obj = window.open("/childwindow.html", "", "width=500, height=500");
}

ウインドウオブジェクト用の変数「obj」を用意しました。

これでウインドウを開ける部分はOK。

値を送る部分

※ローカルでは動かない可能性があるので、
 どこかのサーバーで試す必要があるかもしれません
 (といってもxampp環境はOKでした)

まず、子ウインドウで値を送るには以下のようにすればOK…らしい。

$(obj.document).find('#testid').val('testvalue');

が、window.openの直後に追加してみても動かない。

とりあえず分割して試してみようと、一旦
リンクも関数も「子ウインドウを開く」と「値を送る」の操作に分けてみると動いた。

しばらく考えてから気付いた。
window.openした後、さらに子ウインドウの読み込みが終わってから送らないとダメか…。

とりあえず、試しに「window.openの3秒後に値を送信」とすれば動いた。

jQuery

var obj;
function pushValue(){
    obj = window.open("/childwindow.html", "child", "width=500, height=500");
    setTimeout(function(){
        $(obj.document).find('#testid').val('testvalue');
    },3000);
}

でも読み込みは一瞬で終わるかもしれないし3秒で間に合わないかもしれない。
ので、
「#testidが存在するかどうかを定期的にチェックし、存在すれば送信」
という処理にしてみた。

jQuery

var obj;
function pushValue(){
    obj = window.open("/childwindow.html", "child", "width=500, height=500");
    var timer = setInterval(function(){
        if ($("#testid", obj.document) != undefined){
            $("#testid", obj.document).val('testvalue');
            clearInterval(timer);
        }
    }, 500);
}

必要に応じて整える

ウインドウが既に開かれているかどうかを判定し
開いていなければこれまで書いてきた一連の流れを行い、
開いていればすぐ値を書き換え(つまり後から親ウインドウで操作)…としたかったので、
さっきのかたまりを丸ごとif文で分けた。

タイムアウトとかのロジックを入れた方がいいケースもあるかも。

jQuery

var obj;
function pushValue(){
    if (!obj || obj.closed){
        obj = window.open("/childwindow.html", "child", "width=500, height=500");
        var timer = setInterval(function(){
            if ($("#testid", obj.document) != undefined){
                sendValue();
                clearInterval(timer);
            }
        }, 500);
    }
    else{
        sendValue();
    }
}
function sendValue(){
    $("#testid", obj.document).val("testvalue");
}