Javascript 在IE中处理跨框架的按键

Javascript 在IE中处理跨框架的按键,javascript,internet-explorer,javascript-events,Javascript,Internet Explorer,Javascript Events,我一直在尝试通过javascript(参见我前面的问题)跨多个帧处理onkeydown事件(不,不幸的是我无法摆脱这些帧)。我在另一个框架中获取文档的句柄,并将它的onkeydown处理程序设置为等于我的函数。不会抛出错误,但当我稍后检查文档的设置时,onkeydown为空。我在IE6和IE7中得到了相同的结果。我做错了什么 作用 function setKeyHook(doc) { try{ if (doc

我一直在尝试通过javascript(参见我前面的问题)跨多个帧处理onkeydown事件(不,不幸的是我无法摆脱这些帧)。我在另一个框架中获取文档的句柄,并将它的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中起作用(并且只起作用)。

我让它起作用

frameset.html

试验
frame1.html

第1帧
onload=函数()
{
top.frames.BOTTOM.document.onkeydown=
self.document.onkeydown=函数(evt)
{
返回函数()
{
//只是一个例子来说明它的工作
document.getElementById('output').value+=String.fromCharCode(evt.keyCode);
}
}(窗口事件);
}
框架1
frame2.html

第2帧
框架2
首先,在对象引用中非常明确总是值得的。使用专有的DOM快捷方式(如window.frameName)只会增加不必要的错误可能性。这就是为什么我的脚本显式地在窗口对象的集合中查找

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

  • 窗口-当前窗口。当忽略时也会暗示这一点(即window.onload==onload)
  • 父级-当前窗口的父级窗口
  • 顶部-框架集族中最顶部的窗口父帧==当您只有一个帧集时,将其置于顶部
  • self-窗口的别名
  • 基本上,我在这里做的是,当在frame1窗口中触发onload事件时,为两个框架窗口中的文档向keydown事件添加一个处理程序函数

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


    我希望这是有意义的。

    如果在另一个帧中处理事件时在读取帧的事件对象时遇到问题,则必须显式引用它

    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) {
        ...
        }
    }
    

    编辑!我尽了最大的努力来解释它,但没有变得太冗长。当我从另一个框架调用这个函数时,闭包不起作用(钩子被设置,但evt只传递null)。为什么会这样?我该如何纠正?当你说“从另一个框架调用这个函数”时,你需要更明确。因为如上所述,它是有效的。你现在还想做别的事吗?
    <!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>
    
    <!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>
    
    <!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>
    
    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) {
        ...
        }
    }