Iframes, PDF и фокус с Internet Explorer

Итак, у меня есть страница, содержащая текстовое поле и динамически созданный IFrame, который отображает PDF-файл с помощью плагина Adobe Acrobat.

Первоначально текстовая область сфокусирована.

Я хочу, чтобы текстовое поле было сфокусировано, но IFrame крадет фокус при загрузке PDF-файла.

В firefox тривиально сбросить текстовую область как сфокусированный элемент.

Я делаю это, прослушивая событие «загрузки» iframe, а затем вызывая .focus() в текстовом поле.

M$ IE не запускает событие onload для динамически созданных фреймов, поэтому, чтобы определить, когда он готов, я использую свойство readyState фрейма IFrame:

var ieIframeReadyHandler = function() { 
    if( iframe.readyState=="complete" ) {
           textarea.focus();
    } else {
        setTimeout(ieIframeReadyHandler, 100);
    }
}


setTimeout(ieIframeReadyHandler, 100);

Примечание. Я не слушаю событие readystatechanged iframe, поскольку оно не срабатывает для случая readyState=="complete"!!

Так что же происходит, когда этот код выполняется?..... Ну ничего. PDF-файл Iframe по-прежнему сфокусирован, однако, если я проверю, какой элемент имеет фокус, используя document.activeElement (ранее это был только IE, однако Firefox 3 теперь поддерживает это), мне сообщают, что текстовая область ДЕЙСТВИТЕЛЬНО имеет фокус!!

Что за черт??!?

Есть идеи?


person iasksillyquestions    schedule 24.04.2009    source источник
comment
Каков тип DOM IFRAME (постфикс файла...)   -  person Itay Moav -Malimovka    schedule 24.04.2009
comment
Не знаете, что вы подразумеваете под типом iframe? Насколько я понимаю, type не является свойством элемента DOM для Internet Explorer. Вы имеете в виду тип документа содержимого? Я указываю на pdf, устанавливая свойство src...   -  person iasksillyquestions    schedule 24.04.2009


Ответы (3)


Попробуйте задержать установку фокуса на 200-500 мс. Это довольно распространенная проблема IE.

РЕДАКТИРОВАТЬ:

Используйте событие onLoad в IFRAME:

<body onLoad="parent.window.check_focus()"> .... </body>
person Thevs    schedule 27.04.2009
comment
IFrame будет содержать только содержимое PDF, а не HTML. Таким образом, вы не сможете подключить событие загрузки тела. - person Kirtan; 04.05.2009
comment
@Kirtan: Лучше включить его в элемент ‹body›. Читайте комментарии к следующему ответу. - person Thevs; 04.05.2009

iframe.attachEvent("onload", function(){ }) — это способ iframe onload событий в IE.

person Matthew Wastrodowski    schedule 27.05.2011

В Internet Explorer свойство readystate iframe обновляется только внутри iframe, а не за его пределами. Это по замыслу, по какой-то причине. Нет надежного способа вне iframe определить, загружено ли содержимое iframe.

Если не критично, чтобы iframe отображался сразу при загрузке страницы, вы можете просто подождать, чтобы загрузить его, пока пользователь не запросит его (через ссылку или кнопку). Таким образом, они ожидают этого.

Другая альтернатива, если PDF-файлы размещены локально (или вы не возражаете против кэширования), — это использование Flash и такого инструмента, как PDF2SWF, из SWFTools для преобразования на серверной части.

person Steven Richards    schedule 29.04.2009
comment
Я использовал iframe во времена, предшествующие AJAX, и абсолютно не проблема установить обработчик события iframe onLoad из любого другого окна (используя свойство «родительский»). Например: ‹body onLoad=parent.window.check_load() ... - person Thevs; 30.04.2009
comment
Установка onLoad для элемента body HTML-документа внутри iframe отличается от установки его для самого iframe. Если я вас не понимаю? В случае проблемы ListenToRick содержимое iframe представляет собой PDF-файл, поэтому нет элемента body для установки события. - person Steven Richards; 30.04.2009
comment
свойство readyState действительно изменяется и доступно для родительского js - я продемонстрировал это выше! - person iasksillyquestions; 30.04.2009
comment
Таким образом, я могу успешно вызвать .focus для текстового поля, когда iframe находится в состоянии readyState=complete, и, как я упоминал выше, родительская страница действительно считает, что текстовое поле является сфокусированным элементом для родительской страницы. Возможно, сама родительская страница не сфокусирована? - person iasksillyquestions; 30.04.2009
comment
Проблема в этом случае заключается в том, что состояние готовности неверно. Попробуйте загрузить большой PDF-файл (около 50 МБ). Состояние готовности iframe будет установлено на «завершение» менее чем за секунду, но загрузка PDF еще не завершена! Порядок событий выглядит следующим образом: 1) Плагин загружен (состояние готовности «завершено»), 2) Плагин завершает загрузку первой страницы (установлен фокус на iframe), 3) Плагин продолжает загрузку остальной части документа. Если вы установите фокус между 1 и 2, в большинстве случаев он сразу же будет потерян. Если вы используете более длительную задержку, как указал Thevs, она будет работать правильно при условии, что плагин будет загружен вовремя. - person Steven Richards; 01.05.2009
comment
Как насчет чтения PDF в подготовленный элемент ‹body› этого IFRAME? Я думаю, что в этом случае событие onLoad должно помочь (т.е. запустить после загрузки всего PDF-документа). - person Thevs; 01.05.2009
comment
@Thevs: вы имеете в виду тег «embed» или второй iframe? - person Steven Richards; 01.05.2009
comment
Я не уверен, что вы можете использовать события в теге ‹embed›, но это может быть решением. Также вы можете использовать атрибут src в теге ‹body› iframe. Я даже видел использование ‹img src=... для загрузки PDF-файлов путем изменения типа mime и предварительной загрузки с помощью нового изображения(). - person Thevs; 01.05.2009
comment
Кроме того, вы можете рассмотреть возможность использования скрытого ‹div› с ‹embed› вместо использования IFRAME. Тогда вообще не будет проблем с удержанием фокуса. - person Thevs; 01.05.2009
comment
Да, я почти уверен, что большинство событий плохо работают с тегами ‹embed›. Скрытие ‹div› и ‹embed› может работать так, как вы сказали. В любом случае, чтобы не звучать как заезженная пластинка, но я думаю, что использование SWF-решения было бы гораздо более надежным и не намного более трудоемким, если предположить, что PDF-файлы размещены локально. API Scribd также может помочь. - person Steven Richards; 01.05.2009