- Как закрыть окно браузера с помощью JavaScript
- Как закрыть окно браузера с помощью JavaScript — демонстрация
- Исходный код
- Window. Close Метод
- Определение
- Примеры
- Комментарии
- JavaScript — Объект window: открытие и закрытие окон
- Методы объекта window: open(), close(), print(), focus() и blur()
- Открытие нового окна или вкладки
- Как взаимодействовать с окном после его открытия
- Метод close()
- Метод print()
- Метод focus()
- Метод blur()
- Свойства объекта window: name, opener, closed
- Свойство name
- Свойство opener
- Свойство closed
- Ограничения window.close()
- Почему браузеры ограничивают команду close()?
- Что написано в стандартах?
- Как поступают браузеры?
- ▍Internet Explorer
- ▍Chromium (Microsoft Edge, Google Chrome и другие браузеры)
- ▍Chromium: пользовательский опыт
- ▍Chromium: любопытные факты об очень редкой ошибке
- ▍Safari/WebKit
- ▍Firefox
- Итоги
Как закрыть окно браузера с помощью JavaScript
Чтобы закрыть окно или вкладку браузера, которая была открыта с помощью JavaScript, используйте метод window.close(). Например, приведенный ниже код закроет текущую вкладку.
Метод window.close() будет работать только при следующих условиях:
- Вкладки должны быть открыты с помощью JavaScript. Например, с помощью open().
- В браузере Firefox вкладка, которую вы хотите закрыть, не должны быть открыты с помощью значений параметра strWindowFeatures «noopener» или «noreferrer». Например, если окно было открыто с помощью open(«index.html», «_blank», «noopener»), то функция window.close() не сработает.
Как закрыть окно браузера с помощью JavaScript — демонстрация
Обратите внимание на следующие особенности приведенного ниже примера:
- Кнопка «Open demo» откроет вкладку с этой статьей. При этом браузер автоматически прокрутит страницу до начала раздела с демонстрацией.
- Кнопка «Close current window» отображается как в текущей вкладке, так и во вновь открытой. Но она будет работать только в последней.
- Если вы нажмете кнопку «Open demo» пару раз, то откроете несколько вкладок браузера с этой статьей. При этом кнопка «Close current window» должна работать во всех вкладках браузера. Но кроме оригинальной, которую вы открыли вручную.
Исходный код
Это стандартный HTML-код к с добавлением обработчиков onclick, которые вызываются, когда кто-то нажимает на кнопки.
JavaScript-функция tsw_open_demo_window()вызывается при нажатии кнопки «Открыть демонстрацию».
Window. Close Метод
Определение
Вручную закрывает окно Window. Manually closes a Window.
Примеры
В следующем примере показан файл | меню выхода , обрабатываемого для явного вызова Close . The following example shows a File | Exit menu being handled to explicitly call Close.
Комментарии
WindowМожно закрыть с помощью одного из нескольких хорошо известных, предоставляемых системой механизмов, расположенных в его заголовке, в том числе: A Window can be closed using one of several, well-known, system-provided mechanisms located in its title bar, including:
Системное меню | Закрыть. System menu | Close.
Кнопка » Закрыть «. Close button.
WindowТакже можно закрыть с помощью одного из нескольких хорошо известных механизмов в клиентской области, предоставляемых разработчиками, включая: A Window can also be closed using one of several well-known mechanisms within the client area that are provided by developers, including:
Файл | выйти из главного окна. File | Exit on a main window.
Файл | Закрыть или кнопку Закрыть в дочернем окне. File | Close or a Close button on a child window.
Кнопки ОК и Отмена в диалоговом окне также предоставляются разработчиками, хотя, скорее всего, будет установлено DialogResult , которое автоматически закроет окно, открытое при вызове ShowDialog . OK and Cancel buttons on a dialog box are also developer-provided, although will likely set DialogResult, which automatically closes a window that was opened by calling ShowDialog.
Эти механизмы потребовали явного вызова Close для закрытия окна. These mechanisms require you to explicitly call Close to close a window.
Если окно, открытое путем вызова ShowDialog , и со Button IsCancel свойством, для которого задано значение true, автоматически закроется при нажатии кнопки, или если нажать клавишу ESC. If a window, opened by calling ShowDialog, and with a Button with its IsCancel property set to true, will automatically close when the button is either clicked, or ESC is pressed. Если окно было открыто с помощью Show , Close необходимо явно вызвать метод, например из Click обработчика событий для Button . If the window was opened using Show, however, Close must be explicitly called, such as from Click event handler for the Button.
Закрытие окна приводит к Closing возникновению события. Closing a window causes the Closing event to be raised. Если Closing событие не отменено, происходит следующее: If the Closing event isn’t canceled, the following occurs:
WindowУдаляется из Application.Windows (если Application объект существует). The Window is removed from Application.Windows (if an Application object exists).
WindowУдаляется из владельца, Window если отношение владельца и владелец было установлено до того, как Window было отображено и после открытия владельца Window . The Window is removed from the owner Window if the owner/owned relationship was established before the owned Window was shown and after the owner Window was opened.
Возникает событие Closed. The Closed event is raised.
Неуправляемые ресурсы, созданные объектом, Window уничтожаются. Unmanaged resources created by the Window are disposed.
Если ShowDialog был вызван для отображения Window , ShowDialog возвращает. If ShowDialog was called to show the Window, ShowDialog returns.
При закрытии Window вызывается закрытие всех окон, которыми он владеет. Closing a Window causes any windows that it owns to be closed. Кроме того, закрытие Window может привести к прекращению работы приложения в зависимости от того, как Application.ShutdownMode это свойство задано. Furthermore, closing a Window may cause an application to stop running depending on how the Application.ShutdownMode property is set.
Этот метод не может быть вызван, если окно размещается в браузере. This method cannot be called when a window is hosted in a browser.
JavaScript — Объект window: открытие и закрытие окон
На этом уроке мы познакомимся с различными методами объекта window, которые позволяют открывать и закрывать окна, определять закрыто ли окно, а также получать его внутреннее имя и др.
Методы объекта window: open(), close(), print(), focus() и blur()
В этом разделе мы рассмотрим следующие методы объекта window :
- open() — предназначен для открытия окон (вкладок);
- close() — предназначен для закрытия окон. В основном используется для закрытия окон открытых методом open() ;
- print() — предназначен для печати содержимого окна;
- focus() — предназначен для передачи фокусу указанному окну;
- blur() — предназначен для удаления фокуса с указанного окна.
Открытие нового окна или вкладки
В JavaScript открыть новое окно или вкладку из существующего документа можно с помощью метода « window.open ».
- url – адрес ресурса, который необходимо загрузить в это окно или вкладку (если в качестве url указать пустую строку, то туда будет загружена пустая страница «about:blank»);
- windowName – имя окна;
- windowFeature – необязательный параметр для настройки свойств окна (они указываются в формате «свойство=значение» через запятую и без пробелов).
Настройки окна windowFeature :
- left и top – положение левого верхнего угла окна относительно экрана (значения этих свойств должны быть больше или равны 0);
- height и width — размеры окна (его высота и ширина); основная масса браузеров имеет ограничения на минимальные значения этих свойств (в большинстве случаев – это не меньше 100);
- menubar – во включённом состоянии отображает строку меню;
- toolbar – включает показ кнопок панели инструментов («Назад», «Вперёд», «Обновить» «Остановить») и панель закладок (если она отображается в родительском окне);
- location – определяет нужно ли показывать адресную строку;
- resizable — свойство, которое позволяет включить (yes) или выключить (no) возможность изменения размеров окна;
- scrollbars – предназначено для включения (yes) или выключения (no) полос прокрутки;
- status – определяет нужно ли отображать строку состояния или нет.
Настройки menubar , toolbar , location , resizable , scrollbars , status является логическими, если их нужно включить, то устанавливаем значение true , в противном случае – false .
Рассмотрим следующий примеры:
1. Открыть пустую страницу about:blank в новом окне. Данное окно должно иметь ширину и высоту, равную 250рх:
2. Открыть веб-страницу «http://itchief.ru/» в текущем окне:
3. Открыть новое окно, имеющее определённые свойства (top=100, left=100, width=400, height=500, scrollbars=yes, resizabie=yes):
Как взаимодействовать с окном после его открытия
Метод open() позволяет не только открыть окно, но и получить ссылку на данное окно. Данная ссылка позволяет взаимодействовать с этим окном посредством вызова определённых свойств и методов. Т.е. мы можем с помощью JavaScript кода, расположенного в одном окне управлять другим окном.
Например, для того чтобы обратиться к объекту document открытого окна:
Открыть пустое новое окно и вывести в ней некоторый текст:
Примечание: Взаимодействовать Вы можете только с теми окнами, которые сами открыли, с другими окнами Вы работать не можете.
Метод close()
Он предназначен для закрытия окна. Данный метод не имеет параметров. Он обычно используется для закрытия окон созданных методом open() . В противном случае, когда Вы попытаетесь закрыть окно (вкладку), открытое самим пользователем (не из JavaScript), то браузер из-за соображений безопасности запросит у пользователя подтверждение на выполнение этого действия.
Например, cоздадим кнопки для открытия и закрытия окна с именем myWindow :
Метод print()
Он предназначен для печати содержимого окна. Данный метод не имеет параметров.
Метод focus()
Он предназначен для передачи фокусу указанному окну. Данный метод не имеет параметров.
Метод blur()
Он предназначен, чтобы убрать фокус с указанного окна, т.е. перемещает его на задний план. Данный метод не имеет параметров.
Свойства объекта window: name, opener, closed
В этом разделе рассмотрим следующие свойства объекта window :
- name — предназначено для получения или установления внутреннего имени окна;
- opener — позволяет получить в текущем окне, ссылку на окно (объект window ), с которого было открыто данное окно;
- closed — свойство логического типа, которое возвращает: true , если окно закрыто и false , если окно открыто.
Свойство name
Данное свойство очень часто используется для изменения внутреннего имени окна, после того как оно уже открыто. Кроме этого, свойство name может вернуть текущее значение внутреннего имени окна.
Внутреннее имя окна, это не строка, заключённая между открывающим и закрывающим тегом title — это имя окна которое предназначено для разработчика. Т.е. данное имя невидимо для пользователя.
Данное имя в основном используется в гиперссылках и формах для указания окна, в котором необходимо открыть страницу. Например, для указания внутреннего имя окна в гиперссылке используется атрибут target , Если элемент а имеет атрибут target=»searchWindow» , то при нажатии на данную ссылку браузер сначала пытается найти окно с таким внутренним именем ( searchWindow ), если окна с таким внутренним именем не существует, то он открывает новое окно и присваивает ему имя searchWindow . А если окно с таким именем существует, то новое окно не открывается, а перезагружается страница по указанной ссылке а этом окне. По умолчанию окна а браузере не имеют внутреннего имени.
Например, откроем страницу «http://www.google.com/» в окне, имеющем имя myWindow :
Например, откроем окно с помощью метода open() и выведем в нём его имя:
Свойство opener
Данное свойство позволяет получить в окне, ссылку на исходное окно (объект window ), т.е. на окно из которого было открыто данное окно.
Например, у Вас есть исходное окно (1), в котором Вы с помощью метода ореn() открываете другое окно (2). В этом окне (2) Вы можете с помощью свойства opener получить окно (1).
Свойство closed
Свойство closed возвращает логическое значение, указывающее закрыто окно или нет.
Ограничения window.close()
Порой веб-разработчики с удивлением обнаруживают, что команда windows.close() не всегда закрывает окно браузера. А в консоли инструментов разработчика браузера при этом выводится сообщение, указывающее на то, что скрипты могут закрывать только окна, которые ими же и открыты:
Почему браузеры ограничивают команду close()?
Прежде чем мы перейдём к разговору о том, какие факторы влияют на поведение браузера при вызове close() , важно сначала разобраться с тем, почему вообще существуют ограничения, применяемые при выполнении этой команды.
Иногда такое поведение браузеров объясняют, ссылаясь на некие таинственные «соображения безопасности». Но основная причина ограничений, применяемых к close() , больше связана с тем, что называют «пользовательский опыт». А именно, если скрипты смогут свободно закрывать любые вкладки браузеров, пользователь может потерять важные данные, состояние веб-приложения, работающего во вкладке. Это, кроме того, если вкладка или окно браузера неожиданно закрывается, может привести к нарушению механизмов перемещения по истории посещения страниц. Такие перемещения выполняются браузерными кнопками Вперёд и Назад (в Internet Explorer мы называли этот механизм TravelLog ). Предположим, пользователь применяет вкладку браузера для исследования результатов поиска. Если одна из изучаемых им страниц сможет закрыть вкладку, хранящую стек навигации, историю посещённых страниц, среди которых — страница с результатами поиска, это будет довольно-таки неприятно.
Кое-что тут, конечно, имеет отношение и к безопасности, и к защите пользователей браузеров от мошенников. Например, если браузерные вкладки могли бы свободно сами себя закрывать — это могло бы найти применение на вредоносных страницах, пугающих пользователей, или в каких-нибудь мошеннических схемах.
Что написано в стандартах?
Вот что об этом всём говорится в разделе dom-window-close стандарта HTML:
Контекст просмотра может закрываться скриптами в том случае, если это вспомогательный контекст, созданный скриптом (в отличие от контекста, созданного в результате действий пользователя ), или если это контекст верхнего уровня, история сессий которого содержит только один Document.
Тут, вроде бы, всё достаточно просто и понятно, хотя те части текста, которые я выделил, скрывают в себе много сложностей и тонкостей. (Совершенно закономерным можно счесть такой вопрос: «Что делать, если скрипт был запущен в ответ на действия пользователя?».)
Как поступают браузеры?
К нашему сожалению, у каждого браузера имеется собственный набор моделей поведения, связанный с window.close() (можете поэкспериментировать с этой тестовой страницей). Отчасти это так из-за того, что большинство этих моделей поведения было реализовано до появления соответствующего стандарта.
▍Internet Explorer
В Internet Explorer вкладка или окно браузера закрывается без лишних вопросов в том случае, если для создания этой вкладки или этого окна была использована команда window.open() . Браузер не пытается удостовериться в том, что история посещений страниц вкладки содержит лишь один документ. Даже если у вкладки будет большой TravelLog , она, если открыта скриптом, просто закроется. (IE, кроме того, позволяет HTA-документам закрывать самих себя без каких-либо ограничений).
Во всех других случаях вкладку (или окно) просто так не закрыть: пользователю показывают одно или два модальных окна, что зависит от того, представлена ли страница единственной вкладкой в окне браузера.
Окна для подтверждения закрытия вкладки или окна
▍Chromium (Microsoft Edge, Google Chrome и другие браузеры)
В Chromium 88 команда window.close() выполняется успешно в том случае, если у нового окна или у новой вкладки что-то записано в свойство opener, или в том случае, если стек навигации страницы содержит менее двух записей .
Как видите, тут наблюдается небольшое отличие того, что требует спецификация, от того, что реализовано в браузере.
Во-первых — обратите внимание на то, что я упомянул свойство opener , а не сказал о том, что «страница была создана скриптом». Вспомним о том, что свойство opener позволяет всплывающему окну обращаться к создавшей его вкладке.
- Если пользователь создаёт новую вкладку, щёлкнув по соответствующей кнопке, воспользовавшись комбинацией клавиш Ctrl + T , щёлкнув по ссылке и нажав при этом Shift , открыв URL из командной оболочки, то у открытой в результате вкладки свойство opener установлено не будет.
- А если вкладка была открыта с помощью команды open() или через гиперссылку с заданным атрибутом target (не _blank ), тогда, по умолчанию, в свойство opener записывается некое значение.
- У любой ссылки может быть атрибут rel=opener или rel=noopener , указывающий на то, будет ли у новой вкладки установлено свойство opener .
- При выполнении JavaScript-вызова open() можно, в строке windowFeatures , указать noopener , что приведёт к установке свойства opener новой вкладки в null .
Вышеприведённый список позволяет сделать вывод о том, что и обычный щелчок по ссылке, и использование JavaScript-команды open() может привести к созданию вкладки как с установленным, так и с неустановленным свойством opener . Это может вылиться в серьёзную путаницу: открытие ссылки с зажатой клавишей Shift может привести к открытию вкладки, которая не может сама себя закрыть. А обычный щелчок мыши по такой ссылке приводит к открытию вкладки, которая всегда может закрыть себя сама.
Во-вторых — обратите внимание на то, что в начале этого раздела я, говоря о стеке навигации, употребил слово «записи», а не «объекты Document». В большинстве случаев понятия «запись» и «объект Document» эквивалентны, но это — не одно и то же. Представьте себе ситуацию, когда в новой вкладке открывается HTML-документ, в верхней части которого содержится нечто вроде оглавления. Пользователь щёлкает по ToC-ссылке, ведущей к разделу страницы #Section3 , после чего браузер послушно прокручивает страницу к нужному разделу. Стек навигации теперь содержит две записи, каждая из которых указывает на один и тот же документ. В результате Chromium-браузер блокирует вызов window.close() , а делать этого ему не следует. Этот давний недостаток с выходом Chromium 88 стал заметнее, чем раньше, так как после этого ссылкам с атрибутом target , установленным в _blank , по умолчанию назначается атрибут rel=noopener .
В ветке трекера ошибок Chromium, посвящённой проблеме 1170131, можно видеть, как эту проблему пытаются решить путём подсчёта количества объектов Document в стеке навигации. Но сделать это непросто, так как в настоящее время у процесса, отвечающего за рендеринг страницы, в котором выполняется JavaScript-код, есть доступ только к количеству записей в стеке навигации, но не к их URL.
▍Chromium: пользовательский опыт
Когда браузер Chrome блокирует команду close() , он выводит в консоль следующее сообщение, которое мы уже обсуждали:
А пользователю, который в консоль обычно не смотрит, об этом никак не сообщается. Это может показаться странным тому, кто щёлкнул по кнопке или по ссылке, предназначенной для закрытия страницы. В недавно появившемся сообщении об ошибке 1170034 предлагается показывать пользователю в такой ситуации диалоговое окно, вроде того, что показывается в Internet Explorer. (Между прочим, это сообщение об ошибке задаёт новый стандарт подготовки подобных сообщений. В нём, в виде, напоминающем комикс, показано, как несчастный пользователь превращается в счастливого в том случае, если в Chromium будет реализован предлагаемый функционал.)
▍Chromium: любопытные факты об очень редкой ошибке
То, о чём пойдёт речь, представляет собой весьма хитрый сбой, «пограничный случай», возникающий лишь в особых ситуациях. Но я, в течение пяти лет, встречался с сообщениями о подобном сбое, касающимися и Chrome, и Edge.
Речь идёт о том, что если установить свойство Chromium On Startup (При запуске) в значение Continue where you left off (Восстановить вкладки предыдущего сеанса), перейти на страницу, которая пытается сама себя закрыть, а после этого закрыть окно браузера, то браузер потом, при каждом запуске, будет сам себя закрывать.
Попасть в такую ситуацию довольно сложно, но в Chrome/Edge 90 это вполне возможно.
Вот как воспроизвести эту ошибку. Посетите страницу https://webdbg.com/test/opener/. Щёлкните по ссылке Page that tries to close itself (Страница, которая пытается себя закрыть). Воспользуйтесь сочетанием клавиш Ctrl+Shift+Delete для очистки истории просмотра (стека навигации). Закройте браузер с помощью кнопки X . Теперь попробуйте запустить браузер. Он будет запускаться, а потом сам собой закрываться.
▍Safari/WebKit
Код WebKit похож на код Chromium (что неудивительно, учитывая их генеалогию). Исключением является лишь тот факт, что WebKit не уравнивает переходы по noopener-страницам с переходами, инициированными через интерфейс браузера. В результате пользователь, работая в Safari, может перемещаться по множеству страниц с одного сайта, а команда close() при этом будет работоспособна.
Если же вызов close() окажется заблокированным, то в JavaScript-консоль Safari (надёжно скрытую от посторонних глаз) будет выведено сообщение, указывающее на то, что окно закрыть нельзя из-за того, что оно создано не средствами JavaScript:
▍Firefox
В браузере Firefox, в отличие от Chromium, та часть спецификации HTML, в которой говорится о «только одном Document», реализована корректно. Firefox вызывает функцию IsOnlyTopLevelDocumentInSHistory() , а она вызывает функцию IsEmptyOrHasEntriesForSingleTopLevelPage() , которая проверяет историю сессий. Если там больше одной записи, она уточняет, относятся ли они все к одному и тому же объекту Document. Если это так — вызов close() выполняется.
Firefox даёт в наше распоряжение настройку about:config , называемую dom.allow_scripts_to_close_windows , позволяющую переопределить стандартное поведение системы.
Когда Firefox блокирует close() — он выводит в консоль сообщение о том, что скрипты не могут закрывать окна, которые были открыты не скриптами:
В трекере ошибок Firefox уже 18 лет лежит просьба о том, чтобы браузер показывал бы в подобной ситуации соответствующее окно, а не ограничивался бы выводом сообщения в консоль.
Итоги
Что тут скажешь? Возможно, дело в том, что браузеры — это жутко сложные создания.
Приходилось ли вам сталкиваться с проблемами, вызванными отличиями реализаций чего-либо в разных браузерах?