调用跨框架时,未正确在关闭中正确设置Javascript事件 [英] Javascript event not being set correctly in closure when called cross frame

查看:86
本文介绍了调用跨框架时,未正确在关闭中正确设置Javascript事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在两帧页面的第一帧中有以下代码:

I have the following code in the top frame of a two frame page:

        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;

这适用于原始文档加载,但是当我从另一帧调用此函数时(通常仅在重新加载一帧时),设置了该挂钩,但是当onkeydown函数触发时,它没有接收到适当的参数,而是evt == null.

This works on the original document load, but when I call this function from another frame (usually when only one frame reloads), the hook is set, but when the onkeydown function fires, it dose not recieve the appropriate arguments, instead evt == null.

完整代码如下:

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>   

要重新创建问题,请右键单击底部框架,单击刷新,再单击重置挂钩",然后按键.

To recreate the issue, right click the bottom frame, click refresh, click "Reset Hooks", and press keys.

相关问题:在IE中处理keyPress跨框

我还阅读了 JavaScript闭包上的一篇文章,但是我不确定如何应用.

I've also read an article on Javascript closures, but I'm not sure how it applies.

很抱歉,我的问题太狭窄了,但是我真的不太了解Javascript来解决这个问题.

Sorry for the narrowness of question, but I really don't know Javascript well enough to figure out the trick to this.

推荐答案

这是一种解决方案,它摒弃了处理事件的老方法",而是使用了更加灵活和强大的事件侦听器"模型.这样可以传递事件对象

Here's a solution that ditches the "old way" of handling events, and instead uses the more flexible and powerful "event listener" model. This allows the passing of event objects

请注意,attachEvent()方法仅适用于IE(您在上一篇文章中将其规定为可以-但如果支持其他功能,则需要更改此方法)

Note that the attachEvent() method is IE only (which you stipulated as being ok in your previous post - but you'll need to change this if you support something else)

function setKeyHook()
{
  var botDocument = top.frames.BOTTOM.document;
  var topDocument = top.frames.TOP.document;
  var eventName = 'onkeydown';
  var handlerFunc = top.frames.TOP.handleKeypress;

  //    Clear them first, or else they'll attach twice and thusly, fire twice
  botDocument.detachEvent( eventName, handlerFunc );              
  topDocument.detachEvent( eventName, handlerFunc );

  topDocument.attachEvent( eventName, handlerFunc );
  botDocument.attachEvent( eventName, handlerFunc );
}

以这种方式注册事件侦听器时,适当的事件对象将作为参数自动传递给处理程序函数.

When event listeners are registered this way, the proper event object is automatically passed as an argument to the handler function.

这篇关于调用跨框架时,未正确在关闭中正确设置Javascript事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆