Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
224 lines (140 sloc) 16.2 KB

Открытие окон и методы window

Всплывающее окно ("попап" -- от англ. 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.

  1. Настройки расположения окна:

left/top (число) : Координаты верхнего левого угла относительно экрана. Ограничение: новое окно не может быть позиционированно за пределами экрана.

width/height (число) : Ширина/высота нового окна. Минимальные значения ограничены, так что невозможно создать невидимое окно с нулевыми размерами.

Если координаты и размеры не указаны, то обычно браузер открывает не окно, а новую вкладку.
  1. Свойства окна:

menubar (yes/no) : Скрыть или показать строку меню браузера.

toolbar (yes/no) : Показать или скрыть панель навигации браузера (кнопки назад, вперед, обновить страницу и остальные) в новом окне.

location (yes/no) : Показать/скрыть поле URL-адреса в новом окне. По умолчанию Firefox и IE не позволяют скрывать строку адреса.

status (yes/no) : Показать или скрыть строку состояния. С другой стороны, браузер может в принудительном порядке показать строку состояния.

resizable (yes/no) : Позволяет отключить возможность изменять размеры нового окна. Значение no обычно неудобно посетителям.

scrollbars (yes/no) : Разрешает убрать полосы прокрутки для нового окна. Значение no обычно неудобно посетителям.

  1. Еще есть небольшое количество не кросс-браузерных свойств, которые обычно не используются. Вы можете узнать о них в документации, например 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"*), т.е. совпадают домен, протокол и порт.

Иначе говоря, если новое окно содержит документ с того же сайта.

Больше информации об этом будет позже, в главе <info:same-origin-policy>.

События

Наиболее важные события при работе с окном браузера:

  • 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](https://developer.mozilla.org/en-US/docs/Web/API/window.open) из JavaScript текущей страницы и в нём нет дополнительных вкладок.
Заметим, что JavaScript не может ни свернуть ни развернуть ни "максимизировать" (Windows) окно.

Эти функции операционной системы от Frontend-разработчиков скрыты. Вызовы, описанные выше, в случае свёрнутого или максимизированного окна не работают.

Прокрутка окна

Прокрутка окна требуется, пожалуй, чаще всего. Мы уже говорили о ней в главе info:metrics-window:

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" в ссылках или формах. Иконка открывающегося окошка на ссылке поможет посетителю понять, что происходит и не потерять оба окна из поля зрения.