[javascript] wyświatlanie okna typu tak/nie

0

Chodzi mi o przykładowy kod, polegający na wyświetleniu okna typu prompt (tak/nie) podczas zamykania strony. Problem tkwi jedynie w tym, że nie mam dostępu do edycji sekcji <head> kodu html, jest dostęp tylko do sekcji body (jest tak dlatego, że to jest blog). Jak dodać funkcję do zdarzenia document.unload, i czy jest to w ogóle możliwe i będzie interpretowane w przeglądarkach, skoro nie ma dostępu do nagłówka? Próbowałem szukać, ale do takiego problemu ciężko dobrać słowa kluczowe, więc nic ciekawego nie znalazłem. Z góry dzięki za pomoc

0

Elementy <script> także mogą występować w <body>, z tym nie ma problemu :)

0

Czyli może być?: <script type="text/javascript>
document.onunload+= funkcja
function funkcja(){
var odp = confirm ("czy chcesz wpisać się do księgi gości? :P");
if(odp){window.close()}
else{
window.location = "www.example.com/ksiega_gosci.htm"
}
</script>

Jeszcze jedno pytanie: czy użyta wyżej funkcja window.close zamknie tylko tą kartę, na której jest wyświetlona moja strona? Nie chciałbym, żeby przez wadliwy skrypt zamknęła się cała przeglądarka, gdy on chciał zamknąć jedną kartę.

On^^ = internauta :D
0

Takie blokowanie zamykania okna przeglądarki z błahego powodu jest bardzo niewygodne dla użytkownika, który ma trudności z wyjściem ze strony. Na szczęście są sposoby, żeby to obejść. Zamiast zamykać aktywną zakładkę należy przejść do drugiej zakładki i zamknąć poprzednią. Zakładka nieaktywna przy zamykaniu nie wyświetla blokującego zamykanie komunikatu.

0

Znalazłem bugi w Twoim kodzie... Chyba, że chciałeś tylko zapisać algorytm ;) Więc:

document.onunload+= funkcja

nie zadziała, gdyż: 1. to nie jest C#, 2. document.onulnoad może być niezdefiniowane, 3. na pewno niezdefiniowana jest zmienna funkcja, którą skrypt dojrzy później.

Jeszcze jedno pytanie: czy użyta wyżej funkcja window.close zamknie tylko tą kartę, na której jest wyświetlona moja strona?
Tak, nie zamknie całej przeglądarki. Każda karta ma swój osobny obiekt window.

0
kubARek napisał(a)
  1. na pewno niezdefiniowana jest zmienna funkcja, którą skrypt dojrzy później.

To akurat nieprawda. Na skutek tzw. wyciągania funkcja o nazwie funkcja będzie zdefiniowana już w pierwszej linii skryptu, mimo że deklaracja umieszczona jest niżej. Możesz to sobie sprawdzić.

To dość ważne, bo często się z tego korzysta robiąc (pseudo)klasy. Takie funkcje robią wtedy za metody prywatne i ja umieszczam je na końcu "klasy" (po metodach publicznych), mimo że dzięki wyciąganiu są zdefiniowane już w pierwszej linijce ciała klasy. Może będę musiał zmienić konwencję, bo widzę, że sporo osób jednak tego nie ogarnia.

Co do tego operatora += to masz rację. Jego użycie w tym stylu jest całkowicie niepoprawne. Można go użyć w przypadku onunload (lub innego zdarzenia) jedynie gdy mamy pewność, że jest tam string (w tym kodzie nie mamy i przeważnie nie mamy) i chcemy dodać do niego kod JavaScript w postaci stringu (tu wstawiamy referencję do funkcji -- i dobrze, bo ten drugi sposób byłby ukrytym evalem i jest wysoce niezalecany).

0

Możesz to sobie sprawdzić.
I sprawdzam, w Firebugu ;) Jedna linijka na szybko:

document.onclick=funkcja; funkcja=function(){console.log("klik!"); }

Błąd: funkcja is not defined.

Ale z kolei jeśli definiujemy zmienne przez var:

var dummy=(document.onclick=funkcja),
  funkcja=function(){ console.log("klik!"); };

to już pięknie ładnie chodzi i smiga :) Z tym wyciąganiem generalnie masz rację, ale dotyczy to przypadków w/w typu. Inny przykładzik:

var funkcja= function() {
     wywolajZdarzenie(pobierzNazwe());

}, wywolajZdarzenie = function(nazwa) {
      console.log(nazwa); // wyświetli "klik"

}, pobierzNazwe = function () {
      return "klik";
};
funkcja();
0

@kubARek:
Nie rozróżniasz wyrażenia funkcji od instrukcji funkcji. To dwie zupełnie różne rzeczy. W uproszczeniu, z wyrażeniem funkcji mamy do czynienia wtedy, gdy pierwszy token instrukcji nie jest słowem "function" (sorki, ale tak to jest zdefiniowane w kategoriach parsera ECMAScriptu).

Czyli to np. jest wyrażenie funkcji:

var fun = function() {
  alert('wyrażenie funkcji');
};

Ale to już jest instrukcja funkcji:

function fun() {
  alert('instrukcja funkcji');
};

Wyciąganie dotyczy TYLKO tego drugiego -- instrukcji funkcji. I właśnie instrukcję funkcji miałeś w kodzie, który podał Amateur (a Ty podałeś wyrażenie funkcji i powiedziałeś, że "nie działa" :) ). Wyciąganie instrukcji funkcji działa perfekcyjnie:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>[JS] Wyciąganie</title>
  <script>
    document.onclick = f;
    
    function f() {
      alert('Instrukcja funkcji została wyciągnięta!');
    }
  </script>
</head>
<body>
  <p>Kliknij gdzieś</p>
</body>

</html>

Tylko zapisz to do pliku i odpal w przeglądarce, a nie w jakimś Firebugu. Być może Firebug odpala pojedynczo każdą instrukcję, czy coś -- i przez to może to nie działać. Nie ma to jednak znaczenia. Zgodnie ze specyfikacją języka musi to działać, w przeglądarce działa.

EDIT:
A to, co podałeś, że niby "pięknie chodzi i śmiga", to nie działa:

var dummy=(document.onclick=funkcja),
  funkcja=function(){ console.log("klik!"); };

Tu jest wyrażenie funkcji i żadnego wyciągania nie ma. No dobra: jakieś jest, ale nie wyciąganie wartości funkcji. Po prostu wszystkie symbole zadeklarowane we wszystkich instrukcjach var w funkcji są definiowane i inicjalizowane wartością undefined (jakkolwiek dziwnie by to nie brzmiało) jeszcze przed wykonaniem ciała funkcji. Dlatego już w linijce z dummy możesz użyć symbolu 'funkcja'. Symbol ten już wtedy jest parserowi znany i jego użycie nie powoduje rzucenia wyjątku (bo normalnie użycie niezdefiniowanego symbolu cisnęłoby wyjątkiem). Jednak zmienna 'funkcja' ma wartość undefined aż do drugiej linijki, gdzie jest inicjalizowany literałem funkcji. Więc w pierwszej linijce podstawiasz pod document.onclick wartość undefined.

Wydaje się to dziwne i głupie? Ależ takie właśnie jest! Parę rzeczy w JavaScripcie jest totalnie nieintuicyjnych i nie dziwi mnie, że ich nie ogarniasz -- nawet całkiem zaawansowani programiści sobie z nimi czasem nie radzą. Takie uroki tego języka. Część rzeczy jest w nim rewelacyjnych, część totalnie -- nie oszukujmy się -- popier@!$%nych ;).

Znajomość obydwu grup (a przynajmniej ich większości) sprawia, że w CV pod hasłem 'JavaScript' możesz uczciwie wpisać 'Bardzo dobra znajomość', a nie 'Dobra znajomość'.

0

Cóż, errare humanum est. Dzięki za wytłumaczenie :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1