Проблемът е, че когато извикам window.close()
или self.close()
, прозорецът не се затваря. Изглежда, че има мнение, че в Chrome не можете да затваряте чрез скрипт всеки прозорец, който не е създаден чрез скрипт. Това е очевидно невярно, но независимо от това се предполага, че той все пак ще го направи, дори и да изисква да се появи предупреждение за потвърждение. Това не се случва.
Така че има ли някой реален, функционален и доказан метод за затваряне на прозорец с помощта на нещо като javascript:window.close()
или javascript:self.close()
, който действително прави това, което се очаква, и нещо, което се случва прекрасно във всеки браузър, който НЕ е базиран на Chrome? Всички предложения ще бъдат високо оценени и аз търся решение, специфично за Javascript, нищо JQuery или изпълнение от трета страна.
Актуализация: Макар че голяма част от предложените неща имат сериозни ограничения и проблеми с използваемостта, последното предложение (специфично за TamperMonkey) за използване на // @grant window.close
в заглавието на скрипта често върши работа дори при тези раздели, които обикновено не могат да се справят с метода за затваряне. Макар да не е напълно идеално и да не е обобщено за всеки случай, то е добро решение в моя случай.
Обикновеният javascript не може да затваря прозорци безразборно. Това е функция за сигурност, въведена преди известно време, за да се спрат различни злонамерени експлойти и дразнители.
От последната работна спецификация за window.close()
:
Методът close()
на обектите Window трябва, ако са изпълнени всички изброени по-долу условия, да затвори контекста на сърфиране A:
- Съответният контекст за разглеждане A е затворим за скрипт.
- Контекстът за разглеждане на действащия скрипт е познат на контекста за разглеждане A.
- Контекстът за разглеждане на действащия скрипт има право да навигира в контекста за разглеждане A.
Контекстът на сърфиране е затворим за скрипт, ако е спомагателен контекст на сърфиране, който е създаден от скрипт (за разлика от действие на потребителя), или ако е контекст на сърфиране, чиято история на сесиите съдържа само един документ.
Това означава, с едно малко изключение, че javascript не трябва да може да затваря прозорец, който не е бил отворен от същия javascript.
Chrome позволява това изключение, което не се прилага за потребителски скриптове, но Firefox не го позволява. Имплементацията на Firefox категорично заявява:
Този метод може да бъде извикан само за прозорци, които са били отворени от скрипт, използващ метода
window.open
.
Ако се опитате да използвате window.close
от потребителски скрипт на Greasemonkey / Tampermonkey /, ще получите:
Firefox: Съобщение за грешка: "Scripts may not close windows that were not opened by script.
"
Chrome: просто се проваля безшумно.
Най-добрият начин да се справите с това е да създадете вместо това разширение за Chrome и/или добавка за Firefox. Те могат надеждно да затварят текущия прозорец.
Въпреки това, тъй като рисковете за сигурността, породени от window.close
, са много по-малки за скрипт на Greasemonkey/Tampermonkey; Greasemonkey и Tampermonkey биха могли разумно да предоставят тази функционалност в своя API (като по същество пакетират работата на разширението вместо вас).
Осмислете възможността да направите заявка за функция.
Chrome is currently беше уязвим към експлойта "self redirection". Така че кодът като този работеше по принцип:
open(location, '_self').close();
Това е грешно поведение, ИМО, и сега (приблизително от април 2015 г.) е предимно блокирано. Той все още ще работи от инжектиран код само ако табът е прясно отворен и няма страници в историята на сърфиране. Така че то'е полезно само при много малък набор от обстоятелства.
Въпреки това вариант все още работи в Chrome (v43 & v44) плюс Tampermonkey (v3.11 или по-нова версия). Използвайте изрично @grant
и обикновеното window.close()
. EG:
// ==UserScript==
// @name window.close demo
// @include http://YOUR_SERVER.COM/YOUR_PATH/*
// @grant GM_addStyle
// ==/UserScript==
setTimeout (window.close, 5000);
Благодаря на zanetu за актуализацията. Имайте предвид, че това няма да работи, ако има отворен само един таб. То затваря само допълнителни табове.
Фиреофокс е защитен срещу този експлойт. Така че единственият начин с помощта на javascript е да се осакатят настройките за сигурност, един по един в браузъра.
Можете да отворите about:config
и да зададете
allow_scripts_to_close_windows
на true
.
Ако скриптът ви е за лична употреба, направете това. Ако помолите някой друг да включи тази настройка, той ще бъде умен и оправдан да откаже с предубеждение.
Понастоящем няма еквивалентна настройка за Chrome.
Използвам метода, публикуван от Брок Адамс, и той работи дори във Firefox, ако е иницииран от потребителя.
open(location, '_self').close();
Извиквам го от натискане на бутон, така че е инициирано от потребителя, и все още работи добре, като използвам Chrome 35-40, Internet Explorer 11, Safari 7-8 и също така Firefox 29-35. Тествах с версия 8.1 на Windows и Mac OS X 10.6, 10.9 & 10.10, ако това е различно.
Код на самозатварящ се прозорец (на страницата, който се затваря сам)
Пълният код, който трябва да се използва в отворения от потребителя прозорец, който може да се затваря сам:
window_to_close.htm
JavaScript:
function quitBox(cmd)
{
if (cmd=='quit')
{
open(location, '_self').close();
}
return false;
}
HTML:
<input type="button" name="Quit" id="Quit" value="Quit" onclick="return quitBox('quit');" />
Опитайте тази тестова страница: (Вече е тествана в Chrome 40 и Firefox 35)
http://browserstrangeness.bitbucket.io/window_close_tester.htm
Код за отваряне на прозореца (на страница, която отваря горната страница)
За да работи това, наложената от сигурността съвместимост между браузърите изисква прозорецът, който трябва да бъде затворен, вече да е бил отворен от потребителя чрез щракване върху бутон в рамките на същия домейн на сайта.
Например прозорецът, който използва метода по-горе, за да се затвори, може да бъде отворен от страница, използваща този код (кодът е предоставен от моята примерна страница, към която има връзка по-горе):
window_close_tester.htm
JavaScript:
function open_a_window()
{
window.open("window_to_close.htm");
return false;
}
HTML:
<input type="button" onclick="return open_a_window();" value="Open New Window/Tab" />
Въпреки че го смятате за "очевидно невярно", това, което казвате "изглежда като убеждение", всъщност е правилно. В документацията на Mozilla за window.close се казва
Този метод е позволено да се извиква само за прозорци, които са били отворени от скрипт, използващ метода window.open. Ако прозорецът не е бил отворен от скрипт, в конзолата на JavaScript се появява следната грешка: Скриптовете не могат да затварят прозорци, които не са били отворени от скрипт
Казвате, че се "предполага, че все още го прави", но не мисля, че ще намерите някаква референция, която да подкрепя това, може би сте'запомнили нещо погрешно?