1

我一直在尝试通过 javascript 处理跨多个帧的onkeydown事件(不,不幸的是我无法摆脱这些帧)(请参阅我以前的问题here)。我正在另一个框架中获取文档的句柄,并将它的 onkeydown 处理程序设置为等于我的函数。没有抛出错误,但是当我稍后检查文档的设置时,onkeydown为空。我在IE6IE7中得到了相同的结果。我究竟做错了什么。

  • 功能

        function setKeyHook(doc)
        {
            try{               
                if (doc)
                    if (parent.TOP.handleKeypress){
                        doc.onkeydown = parent.TOP.handleKeypress;
                        logMessage('Attached handler');
                    }
                    else{
                        logMessage('No handleKeypress');
                    }
                else
                    logMessage('No doc');
            }
            catch (ex){
                logMessage(ex.toString());
            }
        }
    
  • 称呼

    setTimeout("setKeyHook(parent.document.getElementById(\"bottom\").document);", 1000);

  • 输出

   附加处理程序
  • 执行后
    BOTTOM.protocol = 超文本传输​​协议
    BOTTOM.onkeypress = null
    BOTTOM.onrowenter = null
    BOTTOM.onmousedown = null

我应该如何跨帧应用相同的事件处理程序?

注意:这需要在 IE6 和 IE7 中工作(并且只工作)。

4

2 回答 2

2

我得到了这个工作

框架集.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
   "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
    <title>Test</title>
</head>
<frameset rows="50%,50%">
    <frame src="frame1.html" name="TOP">
    <frame src="frame2.html" name="BOTTOM">
</frameset>
</html>

框架1.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
   "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
    <title>Frame 1</title>
    <script type="text/javascript">
    onload = function()
    {
        top.frames.BOTTOM.document.onkeydown = 
        self.document.onkeydown = function( evt )
        {
            return function()
            {
                // Just an example to show it's working
                document.getElementById( 'output' ).value += String.fromCharCode( evt.keyCode );
            }
        }( window.event );
    }

    </script>
</head>
<body>
    frame1
    <textarea id="output"></textarea>  
</body>
</html>

框架2.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
   "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
    <title>Frame 2</title>
</head>
<body>
    frame2
    <textarea></textarea>
</body>
</html>

首先,对您的对象引用相当明确总是值得的。使用专有的 DOM 快捷方式(例如window.frameName)只会增加不必要的错误可能性。这就是为什么我的脚本显式查看窗口对象的框架集合的原因。

接下来是在处理框架集时熟悉 DOM 中的各种内置窗口引用。共有4个

  1. window - 当前窗口。省略时也暗示了这一点(即,window.onload === onload)
  2. parent - 当前的父窗口
  3. top - 框架集系列中最顶层的窗口。 当您只有一个框架集时,parent === top 。
  4. 窗口的别名

所以基本上我在这里所做的是,当 onload 事件在 frame1 窗口中触发时,为两个框架窗口中的文档的 keydown 事件添加一个处理函数。

该函数使用闭包来确保 frame1 中生成的事件可用于实际处理程序,而不管哪个窗口生成了 keydown 事件。这是必要的,因为 IE 如何处理事件。其他浏览器在事件发生时创建新的事件对象并将它们传递给事件处理程序,而 IE 只是修改全局事件对象(通过window.event或更简单的事件引用)以反映当前事件。

我希望这是有道理的。

于 2009-06-25T16:11:08.767 回答
0

如果在另一个框架中处理事件时读取某个框架的事件对象时遇到问题,则必须明确引用它

var event = top.frames.BOTTOM.event;

我自己也遇到过这个问题,我的事件处理程序的开头是

var myFrame = top.frames[0];
myFrame.onkeydown = keyboardHandler;

function keyboardHandler(e) {
    if (!e && event) {
        e = event; //For handling the event in IE
    }
    if (!e && myFrame.contentWindow.event) {
        e = myFrame.contentWindow.event; //For handling event in IE6 from inside the iFrame
    }

    if (e) {
    ...
    }
}
于 2009-08-05T23:29:59.313 回答