Navigace

Hlavní menu

 

Submenu

 

Ohleduplné otevírání nových oken s JavaScriptem

V některých případech při otevírání odkazu do nového okna je pro uživatele pohodlnější, aby nevyskakovala další okna, pokud mu již jedno "naše okno" vyskočilo - to je jednoduché, nicméně takové okno se může skrýt v pozadí hlavního okna a uživatel pak nezaregistruje, že se jeho obsah změnil. V tomto článku si proto ukážeme, jak namísto otevření dalšího okna jen přenést již otevřené okno do popředí.

Tento článek volně navazuje na sérii o chytřejším a ohleduplnějším otvírání nových oken. Ačkoli si leckdo řekne, že nastavit odkazu atribut target a do dokumentu v otevíraném okně nastavit na událost onload vykonání metody focus() je triviální (a má svým způsobem pravdu), v naší ukázce vyřešíme více problémů najednou:

  • Atribut target ve vyšších verzích XHTML není podporován, jako náhradu proto použijeme nastavení vlastnosti target v DOM pomocí klientského skriptování.
  • Ne vždy máme možnost zasahovat do dokumentu otvíraného do nového okna, přidání onload="window.focus();" není vždy možné a často ani vhodné, pokud je dokument nějak interaktivní.
  • Abychom mohli ovládat otvírané okno, musíme jej otevřít skriptem prostřednictvím window.open() - to je vpořádku, musíme ovšem zajistit i funkčnost bez podpory skriptování a v případě skriptování ošetřit stav, kdy má klient "vyskakování" oken blokováno.
  • Pokud jsme okno otevřeli pomocí window.open() a zachovali si v proměnné jeho handler, můžeme pak uplatnit metodu focus() - je však třeba se ujistit, že okno nebylo zavřeno dotazem na vlastnost window.closed.
  • V některých aplikacích se nám uživatel v novém okně přihlašuje do nějaké doplňkové aplikace - může jít například o různé nastavování služeb, administrační rozhraní. Pokud budeme schopní již otevřené okno s přihlášeným uživatelem pouze přenést do popředí, uživatel o své přihlášení nepřijde. Pokud bychom na další kliknutí uživatele v hlavním okně otevřeli nové okno, uživatel by o přihlášení přišel (pokud nepoužíváme cookies), což je nepohodlné.

Výsledkem je krátký skript, který umísťujeme do hlavní stránky. Stránka (dokument) v otevíraném okně nás vůbec nemusí zajímat, může být i z úplně cizího serveru a přesto se korektně přenese do popředí, jakmile klikneme na odkaz v mateřské stránce. Prohlédněte si ukázku (zdrojový kód) odkazující také na zadání nového příspěvku do diskuse našeho Interfora a na editaci profilu. Vyzkoušejte přitom chování, když je nové okno otevřeno a je v pozadí, kdy nové okno zavřete a kdy hlavní stránku ukázky obnovíte. Ukázky do fóra a do knihkupectví jsou voleny záměrně, protože zde se ukáže, že uživatel při vhodně navržené aplikaci nepřijde o přihlášení nebo o obsah košíku.

Nejprve si ukažme odkaz pro otevření "chytrého" nového okna:

 <a href="http://interforum.interval.cz/AddPost.aspx?ForumID=38" onclick="return !OpenMyWin(this);">Nový příspěvek</a>

Nové okno je otvíráno funkcí OpenMyWin(). Funkce vrací hodnotu "true", pokud se nové okno podařilo otevřít. Negovanou hodnotu necháváme klíčovým slovem return probublat až na úroveň odkazu - pokud se tedy nové okno nepodaří otevřít (klient má například blokované otvírání nových oken), odkaz zafunguje klasickým způsobem, náš doplněný skript tedy nezpůsobí v našem webu bariéru.

Příklad stránky s funkcí, která jen zamezí zavření okna a upozorní uživatele (žádná přidaná testování, zda zobrazit či nezobrazit varování zde není):

var myTWin = window.myTWin;

function OpenMyWin(link)
{
  link.target = '_MyWin';
  if (myTWin != null && !myTWin.closed)
  {
    myTWin.focus();
    myTWin.location.href = link.href;
  }
  else
  {
    myTWin = window.open(link.href,'_MyWin');
    if (myTWin != null)
      myTWin.focus();
  }
  return myTWin;
}

Ve skriptu si deklarujeme proměnnou myTWin - v té budeme držet objekt otevřeného okna po tom, co nové okno otevřeme. Ve funkci OpenMyWin() nejprve nastavíme vlastnost target odkazu předaného do proměnné link na nějakou hodnotu (v našem případě "_MyWin"), čímž nastavíme, že se odkaz má otevírat do nového okna. Toto se uplatní v situaci, kdy má klient blokováno otvírání oken skriptem.

Dále otestujeme, zda proměnná myTWin odkazující na objekt okna není "null". Pokud není (okno již dříve bylo otevřeno), otestujeme, jestli okno nebylo mezitím zavřeno - má vlastnost closed. Pokud je okno otevřeno, je k dispozici, pak ho přesuneme do popředí metodou focus() a jako novou URL nastavíme location.href okna na "href" předaného odkazu "link".

Pokud okno není otevřeno (nebylo otevřeno nebo bylo již zavřeno), pak prostě otevřeme nové okno metodou window.open(). Výsledek otevření je předán do proměnné myTWin - otestujeme, zda není "null", a pokud ne, přeneseme okno do popředí metodou focus(). Toto přenesení je důležité - může se totiž stát, že mateřské okno někdo obnoví nebo v něm přejde na jinou stránku a tím ztratí obsah proměnné myTWin. Okno s názvem "_MyWin" může ale být stále otevřené, takže odkaz by se zobrazil v něm a uživatel by toto nemusel zaregistrovat.

Ještě důkladnější řešení by předpokládalo zamezit ztrátě obsahu myTWin - to by bylo možné umístěním skriptu do nadřízeného rámce (s ohledem na přístupnost velmi nevhodné), nebo do nějakého třetího okna, které by na procházení stránek v hlavním okně nebylo závislé. Jako návratovou hodnotu funkce tedy nakonec předáme hodnotu myTWin, která, jak již bylo uvedeno, slouží k potlačení nebo naopak provedení původní funkce odkazu.

V části kódu funkce, kde zjistíme, že je okno otevřené, a nastavujeme novou adresu okna, by bylo možné otestovat, zda se aktuální adresa okna rovná té, kterou chceme nastavit. Pokud by adresy byly rovny, nastavení location.href bychom neprovedli - pouze bychom přenesli okno do popředí. Volba postupu závisí na aplikaci - v některých aplikacích je toto "nenastavení adresy" nežádoucí (uživatel mohl v onom okně nejméně jednou odeslat nějaký formulář metodou POST - adresa je tedy stejná, ale obsah stránky ne), v jiných aplikacích je velmi vhodné, protože tak uživateli například nezmizí obsah rozepsaného příspěvku ve formuláři. Naopak do otvíraného okna můžeme doplnit upozornění před zavřením okna.

Jak vidíte, skript neobsahuje žádné konfigurovatelné hodnoty - tak jak leží a běží jej ihned můžete zaintegrovat do libovolné aplikace a odkazů v ní použitých.

Růžička, Pavel (23. 7. 2004)
(odborný redaktor magazínu Interval.cz)

Pop-up okna velebená a proklínaná

Vyskakovací okna jsou jedním z nejspornějších prvků webdesignu vůbec. I v našich článcích můžete pozorovat, jak se měnily způsoby práce s popupy a názory na ně. Tato série článků již byla uzavřena, ačkoli další pokračování nelze vyloučit.

Ohleduplné otevírání nových oken s JavaScriptem (diskuse)
2004-08-01 13:44:50rel$humorné
2004-08-01 18:55:28Vilém Málekhumorné
2004-08-01 23:50:30rel$humorné
2004-08-03 10:53:31Jméno a příjmeníFunguje to! (...Mozilla, Netscape 4.8)
2004-08-16 21:37:36citaFunguje to! (...Mozilla, Netscape 4.8)