Всплывающее окно («попап» – от англ. Popup window) – один из старейших способов показать пользователю ещё один документ.
В этой статье мы рассмотрим открытие окон и ряд тонких моментов, которые с этим связаны.
Простейший пример:
window.open("http://ya.ru");
…При запуске откроется новое окно с указанным URL.
Большинство браузеров по умолчанию создают новую вкладку вместо отдельного окна, но чуть далее мы увидим, что можно и «заказать» именно окно.
Блокировщик всплывающих окон
Рекламные попапы очень надоели посетителям, аж со времён 20-го века, поэтому современные браузеры всплывающие окна обычно блокируют. При этом пользователь, конечно, может изменить настройки блокирования для конкретного сайта.
Всплывающее окно блокируется в том случае, если вызов window.open
произошёл не в результате действия посетителя.
Как же браузер понимает – посетитель вызвал открытие окна или нет?
Для этого при работе скрипта он хранит внутренний «флаг», который говорит – инициировал посетитель выполнение или нет. Например, при клике на кнопку весь код, который выполнится в результате, включая вложенные вызовы, будет иметь флаг «инициировано посетителем» и попапы при этом разрешены.
А если код был на странице и выполнился автоматически при её загрузке – у него этого флага не будет. Попапы будут заблокированы.
Полный синтаксис window.open
Полный синтаксис:
win = window.open(url, name, params)
Функция возвращает ссылку на объект window
нового окна, либо null
, если окно было заблокировано браузером.
Параметры:
url
- URL для загрузки в новое окно.
name
- Имя нового окна. Может быть использовано в параметре
target
в формах. Если позднее вызватьwindow.open()
с тем же именем, то браузеры (кроме IE) заменяют существующее окно на новое. params
- Строка с конфигурацией для нового окна. Состоит из параметров, перечисленных через запятую. Пробелов в ней быть не должно.
Значения параметров params
.
- Настройки расположения окна:
left/top
(число)-
Координаты верхнего левого угла относительно экрана. Ограничение: новое окно не может быть позиционировано за пределами экрана.
width/height
(число)-
Ширина/высота нового окна. Минимальные значения ограничены, так что невозможно создать невидимое окно с нулевыми размерами.
Если координаты и размеры не указаны, то обычно браузер открывает не окно, а новую вкладку.
- Свойства окна:
menubar
(yes/no)- Скрыть или показать строку меню браузера.
toolbar
(yes/no)- Показать или скрыть панель навигации браузера (кнопки назад, вперёд, обновить страницу и остальные) в новом окне.
location
(yes/no)- Показать/скрыть поле URL-адреса в новом окне. По умолчанию Firefox и IE не позволяют скрывать строку адреса.
status
(yes/no)- Показать или скрыть строку состояния. С другой стороны, браузер может в принудительном порядке показать строку состояния.
resizable
(yes/no)- Позволяет отключить возможность изменять размеры нового окна. Значение
no
обычно неудобно посетителям. scrollbars
(yes/no)- Разрешает убрать полосы прокрутки для нового окна. Значение
no
обычно неудобно посетителям.
- Ещё есть небольшое количество не кросс-браузерных свойств, которые обычно не используются. Вы можете узнать о них в документации, например MDN: window.open.
Браузер подходит к этим параметрам интеллектуально. Он может проигнорировать их часть или даже все, они скорее являются «пожеланиями», нежели «требованиями».
Важные моменты:
- Если при вызове
open
указан только первый параметр, параметр отсутствует, то используются параметры по умолчанию. Обычно при этом будет открыто не окно, а вкладка, что зачастую более удобно. - Если указана строка с параметрами, но некоторые
yes/no
параметры отсутствуют, то браузер выставляет их вno
. Поэтому убедитесь, что все нужные вам параметры выставлены вyes
. - Когда не указан
top/left
, то браузер откроет окно с небольшим смещением относительно левого верхнего угла последнего открытого окна. - Если не указаны
width/height
, новое окно будет такого же размера, как последнее открытое.
Доступ к новому окну
Вызов window.open
возвращает ссылку на новое окно. Она может быть использована для манипуляции свойствами окна, изменения URL, доступа к его переменным и т.п.
В примере ниже мы заполняем новое окно содержимым целиком из JavaScript:
var newWin = window.open("about:blank", "hello", "width=200,height=200");
newWin.document.write("Привет, мир!");
А здесь модифицируем содержимое после загрузки:
var newWin = window.open('/', 'example', 'width=600,height=400');
alert(newWin.location.href); // (*) about:blank, загрузка ещё не началась
newWin.onload = function() {
// создать div в документе нового окна
var div = newWin.document.createElement('div'),
body = newWin.document.body;
div.innerHTML = 'Добро пожаловать!'
div.style.fontSize = '30px'
// вставить первым элементом в body нового окна
body.insertBefore(div, body.firstChild);
}
Обратим внимание: сразу после window.open
новое окно ещё не загружено. Это демонстрирует alert
в строке (*)
. Поэтому в примере выше окно модифицируется при onload
. Можно было и поставить обработчик на DOMContentLoaded
для newWin.document
.
Связь между окнами – двухсторонняя.
Родительское окно получает ссылку на новое через window.open
, а дочернее – ссылку на родителя window.opener
.
Оно тоже может его модифицировать.
Если запустить пример ниже, то новое окно заменит содержимое текущего на 'Test'
:
var newWin = window.open("about:blank", "hello", "width=200,height=200");
newWin.document.write(
"<script>window.opener.document.body.innerHTML = 'Test'</scr" + "ipt>"
);
Большинство действий, особенно получение содержимого окна и его переменных, возможны лишь в том случае, если URL нового окна происходит из того же источника (англ. – «Same Origin»), т.е. совпадают домен, протокол и порт.
Иначе говоря, если новое окно содержит документ с того же сайта.
Больше информации об этом будет позже, в главе Кросс-доменные ограничения и их обход.
События
Наиболее важные события при работе с окном браузера:
onresize
– событие изменения размера окна.onscroll
– событие при прокрутке окна.onload
– полностью загрузилась страница со всеми ресурсами.onfocus/onblur
– получение/потеря фокуса.
Методы и свойства
window.closed
- Свойство
window.closed
равноtrue
, если окно закрыто. Может быть использовано, чтобы проверить, закрыл ли посетитель попап. window.close()
- Закрывает попап без предупреждений и уведомлений. Вообще, метод
close()
можно вызвать для любого окна, в том числе, текущего. Но если окно открыто не с помощьюwindow.open()
, то браузер может проигнорировать вызовclose
или запросить подтверждение.
Перемещение и изменение размеров окна
Существует несколько методов для перемещения/изменения размеров окна.
win.moveBy(x,y)
- Перемещает окно относительно текущего положения на
x
пикселей вправо иy
пикселей вниз. Допускаются отрицательные значения. win.moveTo(x,y)
- Передвигает окно в заданную координатами
x
иy
точку экрана монитора. win.resizeBy(width,height)
- Изменяет размер окна на заданную величину
width/height
(ширина/высота). Допускаются отрицательные значения. win.resizeTo(width,height)
- Изменяет размер окна на заданное значение.
Чтобы предотвратить использование этих методов с плохими целями, браузеры часто блокируют их выполнение. Как правило, они работают, если окно win
открыто вызовом window.open из JavaScript текущей страницы и в нём нет дополнительных вкладок.
Заметим, что JavaScript не может ни свернуть ни развернуть ни «максимизировать» (Windows) окно.
Эти функции операционной системы от Frontend-разработчиков скрыты. Вызовы, описанные выше, в случае свёрнутого или максимизированного окна не работают.
Прокрутка окна
Прокрутка окна требуется, пожалуй, чаще всего. Мы уже говорили о ней в главе Размеры и прокрутка страницы:
win.scrollBy(x,y)
- Прокрутка окна на заданное число пикселей вперёд или назад. Допускаются отрицательные значения.
win.scrollTo(x,y)
- Прокручивает окно к заданным координатам.
elem.scrollIntoView(top)
- Этот метод прокрутки вызывается на элементе. При этом окно прокручивается так, чтобы элемент был полностью видим. Если параметр
top
равенtrue
или не задан, то верх элемента совпадает с верхом окна. Если он равенfalse
, то окно прокручивается так, чтобы нижний край элемента совпал с нижним краем окна.
Итого
- Всплывающее окно открывается с помощью вызова
window.open(url, name, params)
. - Метод
window.open
возвращает ссылку на новое окно илиnull
, если окно было заблокировано. - Современные браузеры блокируют окна, если
window.open
вызвано не в результате действия посетителя. - Обычно открывается вкладка, но если заданы размеры и позиция – то именно окно.
- Новое окно имеет ссылку на родительское в
window.opener
. - Окна могут общаться между собой как угодно, если они из одного источника. Иначе действуют жёсткие ограничения безопасности.
Всплывающие окна используются нечасто. Ведь загрузить новую информацию можно динамически, с помощью технологии AJAX, а показать – в элементе <div>
, расположенным над страницей (z-index
). Ещё одна альтернатива – тег <iframe>
.
Но в некоторых случаях всплывающие окна бывают очень даже полезны. Например, отдельное окно сервиса онлайн-консультаций. Посетитель может ходить по сайту в основном окне, а общаться в чате – во вспомогательном.
Если вы хотите использовать всплывающее окно, предупредите посетителя об этом, так же и при использовании target="_blank"
в ссылках или формах. Иконка открывающегося окошка на ссылке поможет посетителю понять, что происходит и не потерять оба окна из поля зрения.