Okna przeglądarki

Za pomocą JavaScript możemy otwierać nowe okna, formatować ich wygląd, przesyłać między nimi informacje itp.

Przez kilka ostatnich lat sporo się pozmieniało w materii otwierania nowych okien. Po pierwsze większość przeglądarek blokuje otwieranie nowych okien na stronach. Po drugie użytkownicy nie lubią gdy próbuje im się narzucić nowe okna. Po trzecie wreszcie - otwieranie okien na urządzeniach mobilnych mija się z celem. Co najwyżej możemy otworzyć stronę w nowej karcie.

Wszystkie te punkty powodują, że nie zalecam otwierania nowych okien, a zamiast ich zalecam używać wszelakiej maści popupów czy modali - najlepiej korzystając z gotowych rozwiązań (1, 2, 3)

Otwieranie nowego okna

Standardowa konstrukcja otwierająca okno ma postać:


const win = window.open(url, name, options)
url ścieżka do otwieranej strony lub pusty ciąg, jeżeli okno generujemy dynamicznie
name nazwa okna, do której możemy się odwoływać atrybutem target w linkach i formularzach. Możemy też tutaj podać target="_blank" jeżeli chcemy otworzyć okno jako nową kartę
options Dodatkowe opcje otwieranego okna, opisane poniżej

Wszystkie możliwe ustawienia znajdziesz na stronie https://developer.mozilla.org/pl/docs/Web/API/Window/open, poniżej zamieszczam te najczęściej używane. Tutaj mała uwaga. Przeglądarki są bardzo wybredne jeżeli chodzi o otwierane okna, dlatego nie wszystkie poniższe właściwości będą wszędzie działać.

left pozycja względem lewej strony ekranu
top pozycja okna względem góry ekranu
height ustawia wysokość okna
width ustawia szerokość okna
menubar (yes/no) pokazuje lub ukrywa menu przeglądarki
toolbar (yes/no) pokazuje lub ukrywa standardowy pasek narzędzi
location (yes/no) pokazuje lub ukrywa pasek adresowy
directories (yes/no) pokazuje lub ukrywa przyciski katalogów
status (yes/no) pokazuje lub ukrywa pasek statusu
resizable (yes/no) określa czy okno może zmienić rozmiar
scrollbars (yes/no) pokazuje lub ukrywa paski przewijania
dialog(yes/no) Usuwa z okna wszystkie menu, statusy itp, zostawiając tylko przycisk zamykania
noopenerZapobiega używaniu zmiennej opener w otwieranych oknach. Patrz poniżej
noreferrerZapobiega wysyłaniu informacji o adresie, z której została otwarta strona w oknie. Dodatkowe informacje możesz zobaczyć tutaj
minizable(yes/no) używane wraz z dialog. Jeżeli ustawimy na yes, dialog dodatkowo będzie można zminimalizować

//otwieram jako nowe okno
const myWin = window.open("http://google.pl", "myWindow", "tolbar=no,scrollbars=no,menubar=no,width=500,height=500");

//otwieram jako nową zakładkę
const newTab = window.open("http://mypage.pl", "target=_blank");

Przykładowa funkcja, która otworzy okno na środku ekranu może mieć postać:


const myWindow = function(url, width, height) {
    const centerH = window.screen.height / 2;
    const centerW = window.screen.width / 2;
    const posX = centerW-width/2;
    const posY = centerH-height/2;

    window.open(url, "tytul-okna", `dialog=yes,width=${width},height=${height},left=${posX},top=${posY}`);
};

const btn = document.querySelector("#testWindow");
btn.addEventListener("click", () => {
    myWindow("http://google.pl", 600, 400);
});

Modyfikacja okna

Dzięki przypisaniu nowego okna pod zmienną, możemy nim w łatwy sposób manipulować. Zasady są identyczne jakie stosowaliśmy w rozdziale o DOM - jedyna różnica polega na odwołaniu, gdzie musimy użyć zmiennej, pod którą podstawimy otwarte okno:


const win = document.open(...);

const p = win.document.querySelectorAll("p");
for (const el of p) {
    p.style.color = "red";
    p.innerHTML = "Lubie koty i psy";
}

win.document.body.addEventListener("click", () => {
    console.log("Kliknąłeś body");
});

Właściwość opener

Jedną z ciekawszych ale i niebezpiecznych właściwości otwartych okien/zakładek jest właściwość opener. Dzięki niej możemy się odwoływać do okna, z którego utworzyliśmy nowe okno.


opener.document.body.style.background = "yellow";

Sprawdźmy to:


const btn = document.querySelector("#windowOpenerTest");
btn.addEventListener("click", () => {
    const win = window.open("window-test-opener.html", "target='_blank'");
})

Jak zauważysz korzystając z właściwości opener, mogę nieźle namieszać na stronie, która otworzyła takie okno.

Może to być początek groźnego ataku. Wyobraź sobie, że zamiast otwierać małe okienko, otworzę stronę w nowej zakładce. Równocześnie mogę np. przekierować stronę, która otworzyła nowe okno za pomocą kodu:


opener.window.location = "https://www.mbąnk.pl/logoutpage.html?type=t"

Ty wracasz na swoją stronę i widzisz, że zostałeś niechcący wylogowany ze swojego konta. Logujesz się i... Właśnie przejąłem twoje hasła do twojego konta, ponieważ zalogowałeś się na fejkową stronę na domenie mbąnk. Jasne - nie każdy z nas ma konto w mBanku. I pewnie większość wzmocni swoją uwagę, gdyby zaistniała powyższa sytuacja.

Ale nie oszukujmy się - przecież wśród nas jest pełno osób, które bardzo łatwo nabierają się na wnuczków policjantów, blokady komputera nakładane przez FBI, lecznicze kołdry itp. A przecież mówimy powyżej o prostym przekierowaniu. Podobne ataki mogą być bardziej wymyślne, bo mogą zmieniać zdarzenia przypisane do elementów, ich html, ustawiać niewidzialne elementy itp.

Z tego też powodu przy otwieraniu nowych okien, powinieneś używać właściwości noopener.


const win = window.open("window-test-opener.html", "target="_blank"", "noopener,....");

Jeszcze w czasach IE11 podobne zabezpieczenie powinieneś stosować w linkach, gdzie otwierasz stronę w nowej zakładce za pomocą target="_blank". Służy do tego atrybut rel="noopener":


<a href="..." target="_blank" rel="noopener"> klik </a>

W dzisiejszych czasach dla linków możesz je pominąć.

Trening czyni mistrza

Jeżeli chcesz sobie potrenować zdobytą wiedzę, zadania znajdują się w repozytorium pod adresem: https://github.com/kartofelek007/zadania

Wszelkie prawa zastrzeżone. Jeżeli chcesz używać jakiejś części tego kursu, skontaktuj się z autorem.
Aha - i ta strona korzysta z ciasteczek.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.