Обрабатывать нажатие клавиш через фреймы в IE

Я пытался обработать событие onkeydown для нескольких кадров (нет, я, к сожалению, не могу избавиться от кадров) с помощью javascript (см. Мой предыдущий вопрос здесь). Я получаю дескриптор документа в другом фрейме и устанавливаю его обработчик 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);

  • Выход

   Прикрепленный обработчик
  • После исполнения
    BOTTOM.protocol = Протокол передачи гипертекста BOTTOM.onkeypress = null
    BOTTOM.onrowenter = null
    BOTTOM.onmousedown = null

Как мне применить один и тот же обработчик событий для всех кадров?

Примечание: это должно работать (и только работать) в IE6 и IE7.

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) просто добавляет ненужный потенциал ошибок. Вот почему мой скрипт явно просматривает коллекцию кадров объекта окна.

Далее следует ознакомиться с различными встроенными ссылками на окна в DOM при работе с наборами кадров. Всего 4

  1. окно - текущее окно. Это также подразумевается, когда не учтено (то есть window.onload === onload)
  2. parent - родительское окно для текущего
  3. top - самое верхнее окно в семействе фреймов. parent === top, когда у вас есть только один набор фреймов.
  4. псевдоним окна

Итак, в основном, что я сделал здесь, когда событие onload срабатывает в окне frame1, это добавление функции обработчика к событию keydown для документов в обоих окнах frame.

Эта функция использует замыкание, чтобы гарантировать, что событие, сгенерированное в frame1, доступно фактическому обработчику, независимо от того, какое окно генерирует событие keydown. Это необходимо из-за того, как IE делает события. В то время как другие браузеры создают новые объекты событий по мере их появления и передают их обработчикам событий, IE просто изменяет глобальный объект события (на который ссылается window.event или более простое событие just), чтобы отразить текущее событие.

Я надеюсь, что в этом есть смысл.

Если у вас возникли проблемы с чтением объекта события фрейма, когда событие обрабатывается в другом фрейме, вам придется явно ссылаться на него

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) {
    ...
    }
}
Другие вопросы по тегам