Опрос
Вы участвуете в программе Windows Insider?
Популярные новости
Обсуждаемые новости

12.04.2011 13:35 | dronov_va

2.4. Доступ из веб-страниц, открытых во фрейме, к основной веб-странице
Давайте запустим наше приложение и посмотрим на него. Мы видим пресловутые кнопки Назад и Вперёд, которые выполняют переход на веб-страницы 1.html и 2.html соответственно. Причём изначально обе эти кнопки доступны.

Но сразу же запуска приложения кнопка Назад не нужна. В самом деле, во фрейме изначально открывается веб-страница 1.html - первая в последовательности. Значит, назад переходить просто некуда. А после загрузки веб-страницы 2.html отпадает нужда в кнопке Вперёд. Поскольку эта веб-страница - последняя в последовательности, вперёд переходить также некуда.

По хорошему, сразу после запуска приложения, а также после перехода на веб-страницу 1.html кнопку Назад надо сделать недоступной. Аналогично, после перехода на веб-страницу 2.html следует сделать недоступной кнопку Вперёд.

Все объекты, представляющие элемент управления, поддерживают свойство disabled. Значение true этого свойства делает элемент управления недоступным, а значение false - доступным. Это значет любой веб-программист средней руки.

Код, управляющий доступностью кнопок, можно поместить прямо в основную веб-страницу Convertor.hta. Но тогда нам придётся как-то отслеживать, какая именно веб-страница в данный момент загружена во фрейм. А это задача нетривиальная и для реализации может потребовать много кода.

Проще всего создать веб-сценарии, управляющие доступностью нужных кнопок, прямо в веб-страницах 1.html и 2.html. Но в таком случае нам понадобится получить доступ к основной веб-странице - Convertor.hta. Как это сделать?

Мы уже знаем, что окно или вкладка браузера представляется экземпляром объекта Window, который доступен в любом веб-сценарии через переменную window. Так вот, с точки зрения веб-страницы, загруженной во фрейме, точно так же представляется и внутреннее пространство этого фрейма. Можно сказать, загруженная во фрейме веб-страница "полагает", что она загружена в окне (вкладке) браузера.

Объект Window поддерживает свойство top. Оно возвращает экземпляр объекта Window, представляющий реальное окно или вкладку браузера, в котором загружена веб-страница с фреймом.

Таким образом, чтобы получить доступ к реальному окну (вкладке) веб-обозревателя из веб-страницы, загруженной во фрейме, нам следует получить значение свойства top экземпляр объекта window.

var oOuterWindow = window.top;


Ещё объект Window поддерживает свойство document. Оно хранит экземпляр объекта HTMLDocument, представляющий загруженную в данное окно (вкладку, фрейм) веб-страницу.

var oMainDocument = oOuterWindow.document;


Примечание:
Ранее мы использовали для доступа к экземпляру объекта HTMLDocument, представляющему текущую веб-страницу, переменную document. Но на самом деле это не переменная, а свойство экземпляра window объекта Window, представляющего текущее окно (вкладку) браузера. Просто при обращении к свойствам и методам экземпляра window можно опускать имя самого этого экземпляра (скажем, вместо window.top писать просто top).

А, получив веб-страницу, мы можем без труда добраться до нужного нам её элемента.

var oBtnBack = oMainDocument.getElementById("btnBack");
oBtnBack.disabled = true;


Примечание:
Данный приём работает только для доверенных фреймов, то есть для тех, чей тег <IFRAME> содержит атрибут APPLICATION со значением yes. Подробнее об этом говорилось в параграфе 2.1.

Вооружившись только что полученными знаниями, напишем веб-сценарии, управляющие доступностью кнопок. Сначала откроем веб-страницу 1.html и поместим в её секцию заголовка вот такой код:

<SCRIPT>
  function setup()
  {
    var oMainDocument = window.top.document;
    var oBtnBack = oMainDocument.getElementById("btnBack");
    var oBtnForward = oMainDocument.getElementById("btnForward");
    oBtnBack.disabled = true;
    oBtnForward.disabled = false;
  }
</SCRIPT>


Эта функция будет делать кнопку Назад недоступной, а кнопку Вперёд - доступной.

Осталось привязать объявленную ранее функцию к веб-странице в качестве обработчика её события load. Это событие возникает сразу после окончания загрузки веб-страницы. Для этого мы исправим тег <BODY>, чтобы он выглядел так:

<BODY ONLOAD="setup();">


После этого откроем веб-страницу 2.html и поместим в её секцию заголовка вот такой код:

<SCRIPT>
  function setupAndConvert()
  {
    var oOuterWindow = window.top;
    var oMainDocument = oOuterWindow.document;

    var oBtnBack = oMainDocument.getElementById("btnBack");
    var oBtnForward = oMainDocument.getElementById("btnForward");
    oBtnBack.disabled = false;
    oBtnForward.disabled = true;
  }
</SCRIPT>


Эта функция будет делать кнопку Назад доступной, а кнопку Вперёд - недоступной. А впоследствии мы заставим эту же функцию выполнять и преобразование величины.

Теперь привяжем данную функцию к веб-странице в качестве обработчика события load. Исправленный тег <BODY> будет выглядеть так:

<BODY ONLOAD="setupAndConvert();">


2.5. Передача данных между веб-страницами, открытыми во фрейме
Наше HTML-приложение будет преобразовывать величины, заданные в дюймах, в миллиметры. Как это делается, мы знаем из первой статьи цикла.

Давайте поместим веб-сценарий, выполняющий это преобразование, в страницу 2.html, поближе к полю ввода Миллиметры, где будет выводиться преобразованная величина. Можно, конечно, поместить его и в основную веб-страницу Convertor.hta, но лучше не загромождать её кодом, относящимся к отдельным "окнам" приложения. Вообще, в основной веб-странице стоит помещать только тот код, который относится либо к ней самой, либо сразу ко всем "окнам", то есть веб-страницам, выводимым во фрейме.

Но при этом возникает проблема. Величина в дюймах вводится в поле ввода Дюймы, расположенном на веб-странице 1.html. Значит, нам как-то нужно передать её веб-странице 2.html, где она должны быть преобразована и выведена на экран. Как это сделать?

Экземпляр объекта Window, представляющий текущее окно, вкладку или внутреннее пространство фрейма, имеет очень интересную особенность. Если мы создадим в веб-сценарии какую-либо переменную, она станет свойством этого экземпляра объекта. А если мы объявим там какую-либо функцию, она станет его методом.

Тогда мы можем объявить в основной веб-странице переменную, с веб-страницы 1.html получить доступ к окну браузера, обратиться к этой переменной как к его свойству, сохранить там введённое значение, а потом, уже на веб-странице 2.html, извлечь его оттуда таким же образом, преобразовать и вывести на экран.

Сказано - сделано!

Откроем основную веб-страницу Convertor.htm и добавим в веб-сценарий, что находится в её секции заголовка, вот такое выражение:

var fInches = 0;


Оно объявляет переменную fInches, где будет храниться введённая величина в дюймах. Хранить мы её будем уже в числовом виде, чтобы облегчить "работу" веб-странице 2.html.

После этого откроем веб-страницу 1.html и поместим в веб-сценарий, присутствующий в её секции заголовка, такой код:

function save()
{
  var oOuterWindow = window.top;
  var oTxtInches = document.getElementById("txtInches");
  oOuterWindow.fInches = parseFloat(oTxtInches.value);
}


Эта функция извлечёт значение, введённое в поле ввода Дюймы, преобразует её в числовой вид и поместит в переменную fInches, что мы объявили на основной веб-странице. Обратим внимание, что мы обращаемся к этой переменной как к свойству экземпляра объекта Window, представляющего окно браузера, где открыта основная веб-страница (последнее выражение тела функции).

Но в каком месте вызвать эту функцию? Вероятно, лучше всего сделать это в обработчике события unload веб-страницы. Это событие возникает сразу перед выгрузкой веб-страницы, а её выгрузка выполняется, в том числе, и перед переходом на другую веб-страницу. То, что нам нужно!

Привяжем объявленную ранее функцию к событию unload веб-страницы. Для этого исправим тег <BODY> таким образом:

<BODY ONLOAD="setup();" ONUNLOAD="save();">


Функцию setup мы объявили ранее, в параграфе 2.4.

Осталось открыть веб-страницу 2.html и добавить в конец кода, создающего тело объявленной там ранее функции setupAndConvert, вот такой фрагмент:

var oTxtMillimetres = document.getElementById("txtMillimetres");
var fMillimetres = oOuterWindow.fInches * 25.4;
oTxtMillimetres.value = fMillimetres;


Он извлечёт из переменной fInches сохранённое там ранее значение, преобразует его в миллиметры и выведет в поле ввода Миллиметры.

Вот теперь наше первое "многооконное" HTML-приложение полностью готово! Можем проверить его в действии.

Напоследок приведём полный код всех трёх веб-страниц, составляющих окончательную версию нашего приложения.

Convertor.hta:

<HTML>
  <HEAD>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">
    <TITLE>Преобразователь</TITLE>
    <HTA:APPLICATION APPLICATIONNAME="appConvertor" BORDER="dialog"
      ICON="Convertor.ico" MAXIMIZEBUTTON="no" SCROLL="no" SELECTION="no"
      SINGLEINSTANCE="yes" VERSION="2.0"></HTA:APPLICATION>
    <SCRIPT>
      window.resizeTo(310, 200);

      var fInches = 0;

      function goBack()
      {
        var oFfr1 = document.getElementById("ffr1");
        oFfr1.src = "1.html";
      }

      function goForward()
      {
        var oFfr1 = document.getElementById("ffr1");
        oFfr1.src = "2.html";
      }
    </SCRIPT>
  </HEAD>
  <BODY>
    <IFRAME ID="ffr1" WIDTH="100%" HEIGHT="70" FRAMEBORDER="0" SCROLLING="no"
      APPLICATION="yes" SRC="1.html"></IFRAME>
    <HR>
    <FORM>
      <DIV STYLE="text-align: right">
        <INPUT TYPE="button" ID="btnBack" VALUE="Назад" ONCLICK="goBack();">
        <INPUT TYPE="button" ID="btnForward" VALUE="Вперёд" ONCLICK="goForward();">
        <INPUT TYPE="button" VALUE="Закрыть" ONCLICK="window.close();">
      </DIV>
    </FORM>
  </BODY>
</HTML>

t;
</HTML>[/code]
1.html:

[code]<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">
<SCRIPT>
function setup()
{
var oMainDocument = window.top.document;
var oBtnBack = oMainDocument.getElementById("btnBack");
var oBtnForward = oMainDocument.getElementById("btnForward");
oBtnBack.disabled = true;
oBtnForward.disabled = false;
}

function save()
{
var oOuterWindow = window.top;
var oTxtInches = document.getElementById("txtInches");
oOuterWindow.fInches = parseFloat(oTxtInches.value);
}
</SCRIPT>
</HEAD>
<BODY ONLOAD="setup();" ONUNLOAD="save();">
<FORM>
<P>Дюймы: <INPUT TYPE="text" ID="txtInches"></P>
</FORM>
</BODY>
</HTML>[/code]
2.html:

[code]<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">
<SCRIPT>
function setupAndConvert()
{
var oOuterWindow = window.top;
var oMainDocument = oOuterWindow.document;

var oBtnBack = oMainDocument.getElementById("btnBack");
var oBtnForward = oMainDocument.getElementById("btnForward");
oBtnBack.disabled = false;
oBtnForward.disabled = true;

var oTxtMillimetres = document.getElementById("txtMillimetres");
var fMillimetres = oOuterWindow.fInches * 25.4;
oTxtMillimetres.value = fMillimetres;
}
</SCRIPT>
</HEAD>
<BODY ONLOAD="setupAndConvert();">
<FORM>
<P>Миллиметры: <INPUT TYPE="text" ID="txtMillimetres" READONLY></P>
</FORM>
</BODY>
</HTML>[/code]
2.6. Доступ из основной веб-страницы к страницам, открытым во фрейме
Напоследок рассмотрим ещё один важный вопрос - как выполняется доступ из основной веб-страницы, содержащей фрейм, к веб-страницам, открытым во фрейме. Во многих случаях это может понадобиться.

Объект HTMLIFrameElement, представляющий плавающий фрейм, поддерживает свойство contentWindow. Оно возвращает экземпляр объекта Window, представляющий внутреннее пространство фрейма. Получив этот экземпляр объекта, мы можем через его свойство document добраться до самой веб-страницы, открытой во фрейме, и сотворить с ней всё, что пожелаем.

Примечание:
Данный приём работает только для доверенных фреймов, то есть для тех, чей тег <IFRAME> содержит атрибут APPLICATION со значением yes. Подробнее об этом говорилось в параграфе 2.1.

[code]var oFfr1 = document.getElementById("ffr1");
var oInnerWindow = oFfr1.contentWindow;
var oInnerDocument = oInnerWindow.document;
var oTxtInches = oInnerDocument.getElementById("txtInches");
var sInches = oTxtInches.value;[/code]
Этот веб-сценарий, будучи помещённым в основную веб-страницу, сделает следующее:

  • получит доступ к фрейму ffr1;
  • получит доступ к внутреннему пространству этого фрейма, которое представляется как окно браузера;
  • получит доступ к веб-странице, открытой в этом фрейме (это будет веб-страница 1.html);
  • получит доступ к полю ввода Дюймы (его имя txtInches) этой веб-страницы;
  • сохранит введённое в это поле ввода значение в переменной sInches.


Примечание:
В документации MSDN также заявлена поддержка объектом HTMLIFrameElement свойства contentDocument, возвращающего экземпляр объекта HTMLDocument, который представляет открытую во фрейме веб-страницу. Однако, насколько удалось выяснить автору, в реальности это свойство не поддерживается. Впрочем, вполне возможно, оно поддерживалось в старых версиях Internet Explorer.


Дополнительные материалы



dronov_va, TheVista.Ru Team
Апрель 2011

Комментарии

Комментариев нет...
Для возможности комментировать войдите в 1 клик через

По теме

Акции MSFT
420.55 0.00
Акции торгуются с 17:30 до 00:00 по Москве
Все права принадлежат © ms insider @thevista.ru, 2022
Сайт является источником уникальной информации о семействе операционных систем Windows и других продуктах Microsoft. Перепечатка материалов возможна только с разрешения редакции.
Работает на WMS 2.34 (Страница создана за 0.14 секунд (Общее время SQL: 0.116 секунд - SQL запросов: 53 - Среднее время SQL: 0.00218 секунд))
Top.Mail.Ru