親子関係の無い別ウィンドウ上のJavascript変数取得



0   名前: ダイ : 2007/04/17(火) 10:44  ID:Q62ylCCH sub-Og
ダイと申します。

# 肝となるのは、親子関係の無い別ウィンドウ上のJavascript変数を取得することが可能か?だと思います。

以下の条件を満たすWEBブラウザ上のオートログアウト機能を作成したいと思っています。
・一定時間イベント(マウスクリック、キー入力)が発生しなかった場合は別のページに遷移する。
・[Shift]+リンククリックや[Ctrl]-Nで等で新たなウィンドウが立ち上がっている場合は、
 これらのウィンドウ全てで、一定時間イベントが発生しなかった場合のみ、別のページに遷移する。
 


=window1.html=ここから==================================
<html>
<head>
<script language="JavaScript">
<!--
window.name="window1";
//-->
</script>

<script language="JavaScript" src="autologout1.js"></script>
</head>
<body onLoad="setTimer()" >
<a href="window2.html" target="_blank" >goto window2.html</a>
<a href="window3.html" target="_blank" >goto window3.html</a>
</body>
=window1.html=ここまで==================================

window2.html,window3.htmlについては
window.name="〜"のみ異なるだけのため省略

=autologout1.js=ここから==================================
var initSec=100;
var count=initSec;
forwardUrl='http://www.google.co.jp';
function resetTimer()
{
count = initSec;
//test1
// w1 = window.open("","window1");
// w1.count=initSec;
//test2
// window.opener.count=initSec;
}

function setTimer()
{
count--;
window.status=' '+count+'[sec]';
if( count <= 0 ){
location.replace(forwardUrl) ;
}
setTimeout( "setTimer()",1000 );
}



if( document.all ){
document.onkeydown = resetTimer;
document.onmousedown = resetTimer;
}
=autologout1.js=ここまで==================================

【現象(問題点)】
・window1.htmlを開いた状態で、100秒間イベント無しで放置すると、オートログアウトページに遷移する。
 イベントを発生させると、window1.htmlのcountの値はリセットされる。(期待どおり)
・window1.htmlを開いた後、window2.htmlのリンクをクリックして、window2.html上でイベントを発生させても、
 window1.htmlのcountの値はリセットされない。(期待値としては、両方のcountの値がリセットされてほしい)

【追加テスト1】
・autologout1.jsの//test1のコメントアウトを外した状態で、window1.html,window2.htmlを開き
 window2.html上でイベントを発生させると、window1.html,window2.html双方のcount値は、リセットされる。
 (ここまでは、期待どおり)
 しかし、この後window1.htmlを閉じて、再びwindow2.html上でイベントを発生させると、空ウィンドウが表示される。
 また、window1.html上でイベントを発生させても、window2.htmlのカウント値はリセットされない。

【追加テスト2】
・autologout1.jsの//test2のコメントアウトを外した状態で、window1.html,window2.htmlを開き
 window2.html上でイベントを発生させると、window1.html,window2.html双方のcount値は、リセットされる。
 (ここまでは、期待どおり)
 しかし、この後window1.htmlを閉じて、再びwindow2.html上でイベントを発生させると、javascriptのエラーが表示される。

【質問(希望)】
・表示させているウィンドウ上で、1つでもイベントが発生した場合、全てのウィンドウのcount値をリセットさせることは
 できないでしょうか?(できることならば、各ページでwindow.nameを定義することなく解決したいです)

・追加テスト2でウィンドウオブジェクトを取得する方法を試してみましたが、対応するウィンドウが表示されていない状態で
  w1 = window.open("","window1");を実行した場合に、windowを立ち上げないという方法は可能でしょうか?

・さらに、[Shift]+リンククリックや[Ctrl]-Nで新たなウィンドウが立ち上がった場合にも、
 全てのウィンドウのcount値をリセットさせることは可能でしょうか?

すみませんが、ご教示、アドバイスをお願い致します。

# 本現象が、JavaScript単独で解決できない場合は、WEBサーバ上にcounterを置いて
# 全てのウィンドウが定周期でそのcounter値を見に行くという方法を考えています。

1   名前: 匿名 : 2007/04/17(火) 10:44  ID:5vHRQeeI sub-Cz
逆順に回答。

> さらに、[Shift]+リンククリックや[Ctrl]-Nで新たなウィンドウが立ち上がった場合にも、全てのウィンドウのcount値をリセットさせる

無理。ActiveX のようなもので OS に問い合わせられるなら別だけど(以前、それでウィンドウ名を得ていたコードなら見たことはある)。

> 表示させているウィンドウ上で、1つでもイベントが発生した場合、全てのウィンドウのcount値をリセットさせること

一度でも window.open で開けば、Window オブジェクトを記憶させることはできる。以下では、window1.html の WindowCollection オブジェクトで情報管理している。

window1.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title>TEST</title>
<script type="text/javascript">

var WindowCollection = [ self ];
WindowCollection.maxSeconds = 10;
WindowCollection.currentSeconds = WindowCollection.maxSeconds;

function setTimer () {
    if (--WindowCollection.currentSeconds) {
        status = WindowCollection.currentSeconds;  // 現在秒確認
        setTimeout (setTimer, 1000);
    } else {
        for (var i = WindowCollection.length; i--; ) {
            WindowCollection[i].location.href = 'http://example.com/';
        }
    }
}

onload = setTimer;

</script>
<script type="text/javascript" src="autologout1.js"></script>
<p>
<a href="window2.html" onclick="return openWindow (this); ">window2</a>
<a href="window3.html" onclick="return openWindow (this); ">window3</a>
</p>

window2.html, window3.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title>TEST</title>
<script type="text/javascript" src="autologout1.js"></script>
<p>
<a href="window2.html" onclick="return openWindow (this); ">window2</a>
<a href="window3.html" onclick="return openWindow (this); ">window3</a>
</p>

autologout1.js:
// WindowCollection is declared in window1.html

function openWindow (uri) {
    var w = open (uri);
    w.WindowCollection = WindowCollection;
    WindowCollection.push (w);
    return false;
}

document.onkeydown = document.onmousedown = function () {
    WindowCollection.currentSeconds = WindowCollection.maxSeconds;
};

onunload = function () {
    for (var i = 0, I = WindowCollection.length; i < I; i++) {
        if (self == WindowCollection[i]) break;
    }
    WindowCollection.splice (i, 1);
};

なお、この方法だと window1.html が閉じられた途端に破綻する(あと、別ウィンドウでリロードないしページ遷移が発生したときも)。各ウィンドウごとに秒数を持たせて同期をとっても良いが、どうするにせよ、ウィンドウを一括管理する機構をどこかに用意する必要がある(サーバと連携がとれるなら、それが最善)。

あと、たぶんエラーハンドリングがものすごく大変。何でこんな場面で別ウィンドウを許しちゃうの?

2   名前: ダイ : 2007/04/17(火) 10:44  ID:Q62ylCCH sub-Og
レスありがとうございます。
やはり、javascriptのみでのウィンドウ管理は難しそうですね。
> 何でこんな場面で別ウィンドウを許しちゃうの?

このアプリケーション自体は、明示的に別ウィンドウを発生させない仕組みとしています。
ただし、2つのページを比較したいという要望があり、
その時には、ユーザが、Shift+リンククリック等で複数のウィンドウを立ち上げるため
可能であれば、それにも対応したオートログアウトの仕組みを作りたいと
考えていた次第です。

ありがとうございました。

一覧へ戻る