在IE中处理keyPress Accross Frames

时间:2009-06-25 15:25:45

标签: javascript internet-explorer javascript-events

我一直试图通过javascript在多个框架中处理 onkeydown 事件(不,我很遗憾无法摆脱框架)(请参阅我之前的问题here)。我正在另一个框架中处理文档,并将它的onkeydown处理程序设置为等于我的函数。不会引发任何错误,但是当我稍后检查文档的设置时, onkeydown 为空。我在 IE6 IE7 中获得了相同的结果。我做错了什么。

  • 功能

        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);

  • 输出

   Attached handler
  • 执行后
    BOTTOM.protocol = HyperText Transfer Protocol
    BOTTOM.onkeypress = null
    BOTTOM.onrowenter = null
    BOTTOM.onmousedown = null

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

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

2 个答案:

答案 0 :(得分:2)

我让这个工作

frameset.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>

frame1.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>

frame2.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 )只会增加不必要的错误潜力。这就是我的脚本明确查看窗口对象的 frames 集合的原因。

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

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

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

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

    我希望这是有道理的。

答案 1 :(得分: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) {
    ...
    }
}