Возврат на opener вкладку браузера после закрытия дочерней (открытой по window.open)
Открываем вкладку 1, открываем вкладку 4 с посторонним сайтом. Возвращаемся на вкладку 1. Из вкладки 1 открываем новую вкладку 2 через window.open. Из вкладки 2 открываем новую вкладку 3 через window.open.
Пользователь закрывает вкладку 3 через window.close, становится активной вкладка 2. Вкладку 2 закрывает через window.close. Становится активной вкладка 4 с посторонним сайтом. Почему не выполняется возврат на вкладку 1?
Логика выглядит так: браузер запоминает последний opener, при этом если перед закрытием была открыта другая вкладка - возврат будет на следующую после закрытой. Как будто opener запоминается до следующего перехода на другую вкладку.
Вкладки 1, 2, 3 принадлежат одному домену. Вкладка 4 может быть открыта в любое время.
Пробовал так же прокидывать событие и на родительской и делать window.focus(); Код отрабатывает, но действие не происходит.
Не нашел нигде точного объяснения такому поведению, везде +- "особенности политик безопасности браузера". Chrome (135, 105), Mozilla работают одинаково. Может быть, кто-то точно знает, почему такое поведение?
upd: не работает ни один из возможных вариантов, будь то window.focus(), обращение через opener, подмена window.location.href и т.п. Видимо, политики безопасности браузера не позволяют делать такое.
index.html
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Главная страница</title>
</head>
<body>
<h1>Главная страница</h1>
<p>Нажмите кнопку, чтобы открыть Страницу 1 в новой вкладке.</p>
<button onclick="openPage1()">Открыть Страницу 1</button>
<script>
function openPage1() {
window.open('page1.html', '_blank'); // Открываем page1.html в новой вкладке
}
</script>
</body>
</html>
page1.html
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Страница 1</title>
</head>
<body>
<h1>Страница 1</h1>
<p>Это Страница 1. Нажмите кнопку, чтобы открыть Страницу 2 в новой вкладке.</p>
<button onclick="openPage2()">Открыть Страницу 2</button>
<button onclick="window.close()">Закрыть это окно</button>
<script>
function openPage2() {
window.open('page2.html', '_blank'); // Открываем page2.html в новой вкладке
}
</script>
</body>
</html>
page2.html
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Страница 2</title>
</head>
<body>
<h1>Страница 2</h1>
<button onclick="window.close()">Закрыть это окно</button>
</body>
</html>
Ответы (1 шт):
Как я понял, задача состоит в том, чтобы из вкладки 1 открыть вкладку 2, а при нажатии на какую-то кнопку на вкладке 2, вкладку 2 закрыть и вернуться на вкладку 1. Дело в том, что дочерняя вкладка не может командовать родительской, но родительская может командовать дочерней. Поэтому мы из дочерней вкладки посылаем сообщение в родительскую, а затем уже родительская принимает на себя фокус и закрывает дочернюю.
- При создании дочерней вкладки 2, запоминаем её и переключаемся на дочернюю:
function onCreateWindow2(){
window.addEventListener('message', handleEvent, false); // слушатель сообщений
var window2 = window.open(location, 'window2');
window2.focus();
}
- Во вкладке 2 по нажатию на кнопку закрытия передаём сообщение вкладке 1:
function onClose(){
if (!window.opener) { // родительская вкладка пропала...
alert('???');
return;
}
const d = {}; // какие-то данные, передаваемые вв вкладку 1
window.opener.postMessage({d, action:'close'}, window.opener.location.href);
}
- Во вкладке 1 ловим сообщение и обрабатываем:
function handleEvent(event){
if (event.origin !== window.origin) {
return;
}
if (event.data.action == 'close') {
window.focus();
window2.close();
window.removeEventListener('message', handleEvent, false); // слушатель больше не нужен
...
дальше обрабатываем пришедшие данные
}
}