2フレームページのトップフレームに次のコードがあります。
function setKeyHook()
{
logMessage("setKeyHook()");
top.frames.BOTTOM.document.onkeydown =
top.frames.TOP.document.onkeydown = function( evt )
{
return function(){
top.frames.TOP.handleKeypress(evt);
};
}( window.event );
}
onload = setKeyHook;
これは元のドキュメントの読み込みで機能しますが、別のフレームからこの関数を呼び出すと(通常、1つのフレームのみがリロードされる場合)、フックが設定されますが、onkeydown関数が起動すると、適切な引数を受け取らず、代わりにevt ==ヌル。
完全なコードは次のとおりです。
KeyFrameTest.asp
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
<title>KeyFrameTest</title>
</head>
<frameset Rows="80%,20%">
<frame id="TOP" name="TOP" src="KeyFrameTestTop.asp">
<frame id="BOTTOM" name="BOTTOM" src="KeyFrameTestBottom.asp">
</frameset>
</html>
KeyFrameTestTop.asp
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
<script type="Text/Javascript">
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g,"");
}
NumElements = 5;
//Alt Vals
ControlCode = 1;
ShiftCode = 2;
ControlShiftCode = 3;
//Key Vals
keyR = 82;
keyJ = 74;
keyI = 73;
keyT = 84;
keyEnter = 13;
//Array Indexs
AltIndex = 0;
KeyIndex = 1;
FuncIndex = 2;
KeyFuncMap = new Array(NumElements);
for (i = 0; i < KeyFuncMap.length; ++i)
{
//Three elements, control or shift, key, function
KeyFuncMap[i] = new Array(3);
}
KeyFuncMap[0][AltIndex] = ControlCode;
KeyFuncMap[0][KeyIndex] = keyR;
KeyFuncMap[0][FuncIndex] = "parent.TOP.logMessage(\"Ctrl + R\")";
KeyFuncMap[1][AltIndex] = ControlCode;
KeyFuncMap[1][KeyIndex] = keyJ;
KeyFuncMap[1][FuncIndex] = "parent.TOP.logMessage(\"Ctrl + J\")";
KeyFuncMap[2][AltIndex] = ControlCode;
KeyFuncMap[2][KeyIndex] = keyI;
KeyFuncMap[2][FuncIndex] = "parent.TOP.logMessage(\"Ctrl + I\")";
KeyFuncMap[3][AltIndex] = ControlCode;
KeyFuncMap[3][KeyIndex] = keyT;
KeyFuncMap[3][FuncIndex] = "parent.TOP.logMessage(\"Ctrl + T\")";
KeyFuncMap[4][AltIndex] = ControlCode;
KeyFuncMap[4][KeyIndex] = keyEnter;
KeyFuncMap[4][FuncIndex] = "parent.TOP.logMessage(\"Ctrl + Enter\")";
function CompleteEvent(e)
{
e.cancelBubble = true;
e.returnValue = false;
}
function logMessage(msg)
{
logBox = parent.TOP.document.getElementById("logBox");
if( logBox.value.trim().length < 1 )
{
logBox.value = msg;
}
else
{
logBox.value = logBox.value + "\r\n" + msg;
}
}
function handleKeypress(e)
{
logMessage("handleKeypress(e)");
e = e || window.event ;
if (e == null)
{
logMessage("handleKeypress(e): e == null");
return false;
}
controlVal = getControlVal(e);
for (i = 0; i < KeyFuncMap.length; i++)
{
if (KeyFuncMap[i][AltIndex] == controlVal &&
KeyFuncMap[i][KeyIndex] == e.keyCode)
{
eval(KeyFuncMap[i][FuncIndex]);
CompleteEvent(e);
}
}
}
function getControlVal(e)
{
if (e.ctrlKey && e.shiftKey)
{
return 3;
}
else if (e.ctrlKey)
{
return 1;
}
else if (e.shiftKey)
{
return 2;
}
else return 0;
}
function displayEverything()
{
displayProps(top.frames.TOP, "top.frames.TOP", 0, 1);
displayProps(top.frames.BOTTOM, "top.frames.BOTTOM", 0, 1);
}
function clearLog()
{
logBox = parent.TOP.document.getElementById("logBox");
logBox.value = "";
}
function displayProps(o, name, level, maxLevel)
{
try {
if (level > maxLevel)
return;
for (prop in o){
logMessage(name + "." + prop + " = " + o[prop]);
if (typeof(o[prop]) == "object" && o[prop] != o){
displayProps(o[prop], name + "." + prop, level + 1, maxLevel);
}
}
}
catch (ex){
logMessage(ex.toString());
}
}
function setKeyHook()
{
logMessage("setKeyHook()");
top.frames.BOTTOM.document.onkeydown =
top.frames.TOP.document.onkeydown = function( evt )
{
return function(){
top.frames.TOP.handleKeypress(evt);
};
}( window.event );
}
onload = setKeyHook;
</script>
</head>
<body>
<h1>Hello</h1>
<textarea id="LogBox" rows="20" cols="80"></textarea><BR>
<input type="Button" value="Display Properties" onClick="displayEverything();"/>
<input type="Button" value="Clear Log" onClick="clearLog();"/>
</body>
</html>
KeyFrameTestBottom.asp
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
</head>
<body>
<p>Press Keys Here</p>
<input type="Button" value="Reset Handlers"
onclick="top.frames.TOP.setKeyHook();">
</body>
</html>
問題を再現するには、下部のフレームを右クリックし、[更新]をクリックして、[フックのリセット]をクリックし、キーを押します。
関連する質問:IEのフレーム間でkeyPressを処理する
Javascriptクロージャに関する記事も読んだことがありますが、どのように適用されるのかわかりません。
質問が狭かったことをお詫びしますが、これの秘訣を理解するのに十分なJavascriptを本当によく知りません。