Всплывающее окно («попап» – от англ. 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" в ссылках или формах. Иконка открывающегося окошка на ссылке поможет посетителю понять, что происходит и не потерять оба окна из поля зрения.
Комментарии
<code>, для нескольких строк кода — тег<pre>, если больше 10 строк — ссылку на песочницу (plnkr, JSBin, codepen…)