Документация по JavaScript
2.14. Примеры манипулирования окнами
Как это не покажется странным, но в наших простых примерах мы уже начали манипулировать окнами. Открытие окна-пердупреждения - это операция над объектом "окно". Определим свойства объекта "окно", методы изменения этих свойств и события, которые могут быть связаны с объектом типа "окно". При этом мы не ставим перед собой задачи описания всех известных в JavaScript свойств, методов и событий, связанных с объектами этого класса. Определим только те, которые понадобятся в наших примерах.
Методы
Методы позволяют нам создать на экране видимое окно, закрыть окно и проделать с ним другие операции. С методом window.alert мы уже знакомы. Методы window.confirm и window.prompt используются для получения ответов от пользователя:
Пример 2.16. Использование методов Alert, Prompt, Confirm
<HTML> <HEAD> <title>Window simple example</title> </HEAD> <BODY> <center> <h1>Simple window methods</h1> <hr> </center> <ul> <li><a href="javascript:window.alert ('Attention!!! press the button to continue.') ">Метод Alert.</a> <li><a href="javascript:window.status =window.confirm('Answer yes or no.');void(0); ">Метод Confirm.</a> <li><a href="javascript:window.status =window.prompt('Type string here:','');void(0); ">Метод Prompt.</a> </ul> </BODY> </HTML>
В данном примере при вызове метода confirm появляется окно с просьбой подтверждения некоторого действия, при использовании метода prompt - окно с приглашением ввести информацию в поле ввода. В двух последних случаях если не указать функции void(0), произойдет замещение текста HTML-документа на значение, которое возвращают эти два метода. Если внимательно смотреть за полем окна навигатора, в котором отображается информация о загрузке документов, то там можно будет увидеть возвращаемые значения, т.к. они присваиваются свойству status текущего окна, которое связано именно с этим полем, и которому можно присваивать значения, и, следовательно, эти значения будут отображаться в этом поле.
Однако, следует признать, что рассмотренные выше методы используются крайне редко. А тем более в приведенном здесь контексте, поэтому поспешим рассмотреть методы открытия и закрытия окна.
Открыть окно можно используя метод open:
Пример 2.17. Метод window.open
<HTML> <HEAD> <title>Window simple example</title> </HEAD> <BODY> <center> <h1>Open window methods</h1> <hr> </center> Если выбрать гипертекстовую ссылку <a href="javascript:window.open('simple8.htm', 'example','scrollbars, resizable,width=300,height=200');void(0); ">Открыть окно</a>, то будет открыто новое окно. Чаще всего этот прием используют при создании контекстно зависимых меню. </BODY> </HTML>
В данном случае при выборе гипертекстовой ссылки будет открыто окно шириной 300 пикселей и высотой 200 пикселей, в окне не будет никаких стандартных меню навигатора, и в окно будет загружен документ simple8.html. Метод open позволяет также определить области прокрутки, наличие или отсутствие стандартных меню навигатора и возможность изменения размеров окна. Последняя возможность зависит от платформы на которой исполняется скрипт.
Документ simple8.htm в свою очередь содержит код, который позволяет закрыть окно, открытое в примере 2.17:
Пример 2.18. Закрыть текущее окно
<HTML> <HEAD> <title>Window simple example</title> </HEAD> <BODY> <center> <h1>Close window methods</h1> <hr> </center> Если выбрать гипертекстовую ссылку <a href="javascript:window.close();void(0);"> Закрыть окно</a>, то данное окно будет закрыто. </BODY> </HTML>
В данном примере в качестве гипертекстовой ссылки используется ссылка на метод widow.close(), который закрывает текущее окно. На применении методов open и close построен принцип построения help. По методу open открывается окно подсказки. В него загружают текст документа-подсказки с заранее заготовленной ссылкой на закрытие окна. При выборе этой ссылки окно подсказки закрывается, и пользователь продолжает работать с основным окном навигатора.
Рассмотрим еще один метод, связанный с окном - метод scroll. Данный метод позволяет организовать прокрутку текста в окне.
Пример 2.19. Прокрутка текста в окне навигатора
<HTML> <HEAD> <title>Scroll text</title> </HEAD> <BODY> <center> <h1>Прокрутка текста в окне навигатора</h1> <hr> [<a href="javascript:for(i=0;i<80;i++) {window.scroll(0,i*10)};void(0);"> Прокрутить текст</a>] <hr> </center> Вообще говоря, проверить тип программы просмотра можно на сервере протокола HTTP и передать программе просмотра уже готовую страницу без условной генерации ее ... <hr> <center>[<a href=#top>Вернуться в начало</a>]</center> </BODY> </HTML>
От метода прокрутки мы перейдем теперь к методу, который позволит нам прокручивать документ более равномерно - это метод setTimeout. Большинству пользователей Web он знаком по бегущим строкам в поле статуса программы-навигатора. Метод setTimeout позволяет отложить выполнение функции, которая указывается в качестве аргумента на определенное количество миллисекунд. Системы прокрутки в этом случае рекурсивно вызывают свое выполнение через этот метод и тем самым порождают бесконечный цикл прокрутки.
Пример 2.20. Прокрутка текста по таймеру
<HTML> <HEAD> <title>Scroll text</title> <script language=JavaScript> <!-- i=0;flag=0;start_stop=0; function my_scroll() { if(start_stop==1) { window.scroll(0,i*10); if(flag==0) i++; if(flag==1) i--; if(i>80) {i=80;flag=1;} if(i<0) {i=0;flag=0;} } setTimeout("my_scroll()",500); } function kuku() { if(start_stop == 0) { start_stop =1; } else { start_stop =0; } } // --> </script> </HEAD> <BODY onLoad=my_scroll()> <center> <h1>Прокрутка текста в окне навигатора</h1> <hr> [<a href="javascript:kuku();void(0);"> Запустить/Остановить</a>] <hr> </center> Вообще говоря, проверить тип программы просмотра можно на сервере протокола HTTP и передать программе просмотра уже готовую страницу без условной генерации ее ... <hr> <center>[<a href=#top>Вернуться в начало</a>]</center> </BODY> </HTML>
В данном примере мы не стали писать текст программ в самих гипертекстовых ссылках и вынесли его в заголовок документа. В данном случае это облегчает чтение текста и отладку программы. Текст прокручивается через каждые 500 миллисекунд, что делает прокрутку более плавной. В примере мы впервые применили событие onLoad. Это событие запускает процесс выполнения нашей функции. Прокрутка текста осуществляется в двух направлениях: сначала снизу вверх, а по достижении конца документа сверху вниз.
Следует подробно остановиться на особенностях исполнения метода setTimeout. Особенно в части запуска и останова процедуры прокрутки. Рассматривать алгоритм ее исполнения лучше всего в контексте многопоточных или многозадачных систем. Функция my_scroll - это отдельный процесс (поток), который исполняется программой-навигатором. В момент, когда интерпретатор навигатора встречает метод setTimeout, он создает новый процесс (поток), эквивалентный функции my_scroll, и откладывает его исполнение на 500 миллисекунд. После этого он продолжает выполнять текущий процесс (поток). В нашем случае вызов метода setTimeout - это последняя команда функции my_scroll, поэтому после нее ничего не выполняется, а сам процесс или поток, связанный с текущей функцией my_scroll после обработки setTimeout уничтожается. Однако, новый процесс (поток) уже создан в памяти и ждет начала своего исполнения.
В нашем примере новый процесс поток порождается всякий раз, как интерпретатор достигает метода setTimeout, а уничтожается, когда интерпретатор доходит до последнего оператора этого потока. Такой алгоритм выполнения заставляет расположить вызов setTimeout за пределами блока проверки условий скроллинга. Если мы расположим его внутри, то при останове скроллинга новый процесс не будет порожден, а это значит, что и кода, который будет реагировать на флаг скроллинга после останова, не будет существовать, т.е. запустить скроллинг не будет никакой возможности. Именно по этой причине функция my_scroll начинает исполняться сразу после загрузки документа по событию onLoad, но т.к. флаг скроллинга 0, то прокрутки текста не происходит. Процесс порождается все время, пока страница загружена в текущее окно навигатора.
Во второй версии навигатора данная функция была реализована не очень аккуратно, что приводило к переполнению программного стека и краху программы-навигатора.