Od czasu do czasu natknąłem się na stronę internetową, która próbuje otworzyć nowe okno (w celu wprowadzenia danych przez użytkownika lub czegoś ważnego), ale blokada wyskakujących okienek zapobiega temu.
Jakich metod może użyć wywołujące okno, aby upewnić się, że nowe okno zostało uruchomione poprawnie?
Wypróbowałem kilka powyższych przykładów, ale nie mogłem zmusić ich do pracy z Chrome. Wydaje się, że to proste podejście działa w Chrome 39, Firefox 34, Safari 5.1.7 i IE 11. Oto fragment kodu z naszej biblioteki JS.
źródło
Aktualizacja: Popupy istnieją od naprawdę starożytnych czasów. Początkowym pomysłem było pokazanie innej treści bez zamykania głównego okna. Obecnie istnieją inne sposoby, aby to zrobić: JavaScript może wysyłać żądania do serwera, więc wyskakujące okienka są rzadko używane. Ale czasami są nadal przydatne.
W przeszłości złe strony często nadużywały wyskakujących okienek. Zła strona może otwierać mnóstwo wyskakujących okienek z reklamami. Dlatego teraz większość przeglądarek próbuje blokować wyskakujące okienka i chronić użytkownika.
Większość przeglądarek blokuje wyskakujące okienka, jeśli są wywoływane poza programami obsługi zdarzeń wyzwalanymi przez użytkownika, takimi jak onclick.
Jeśli się nad tym zastanowić, to trochę skomplikowane. Jeśli kod znajduje się bezpośrednio w module obsługi onclick, to jest to łatwe. Ale co otwiera wyskakujące okienko w setTimeout?
Wypróbuj ten kod:
Wyskakujące okienko otwiera się w przeglądarce Chrome, ale jest blokowane w przeglądarce Firefox.
… Działa to również w Firefoksie:
Różnica polega na tym, że Firefox traktuje limit czasu 2000 ms lub mniejszy jest akceptowalny, ale po nim - usuwa „zaufanie”, zakładając, że teraz jest ono „poza akcją użytkownika”. Więc pierwszy jest zablokowany, a drugi nie.
Oryginalna odpowiedź, aktualna w 2012 roku:
Mam nadzieję że to pomoże! :)
źródło
Content-Disposition: attachment;
w nagłówku odpowiedzi), wyskakujące okienko zostanie natychmiast zamknięte, dlategosetTimeout
kod nie powiedzie się, a przeglądarka będzie narzekać, że „Blokowanie wyskakujących okienek jest włączone!”. W przypadku Chrome polecam rozwiązanie @ DanielB i działa świetnie.Content-Disposition: attachment;
nagłówek, nie musisz otwierać go w wyskakującym okienku. Po prostu umieść bezpośredni link do zasobu, który chcesz pobrać, a natywne zachowanie przeglądarki pozwoli na pobranie bez przekierowywania Cię z bieżącej strony.window.location
, jeśli wygenerowanie pierwszego pliku trwa zbyt długo, zostanie zignorowany, gdy rozpocznie się drugie żądanie. To jest powód, dla którego muszę używaćwindow.open
, ponieważwindow.location
nigdy nie informuje mnie, kiedy kończy się odpowiedź.Jednym z „rozwiązań”, które zawsze będzie działać niezależnie od firmy lub wersji przeglądarki, jest po prostu umieszczenie komunikatu ostrzegawczego na ekranie, gdzieś blisko elementu sterującego, który utworzy wyskakujące okienko, które uprzejmie ostrzega użytkownika, że działanie wymaga wyskakującego okienka up i proszę je włączyć na stronie.
Wiem, że to nie jest wyszukane ani nic takiego, ale nie może być prostsze i wymaga tylko około 5 minut testowania, a potem możesz przejść do innych koszmarów.
Gdy użytkownik zezwoli na wyświetlanie wyskakujących okienek w Twojej witrynie, rozważ również, czy nie przesadzasz z wyskakującymi okienkami. Ostatnią rzeczą, którą chcesz robić, jest drażnienie odwiedzających.
źródło
Połączyłem rozwiązania @Kevin B i @ DanielB.
To jest dużo prostsze.
Stosowanie:
źródło
isPopupBlockerActivated
funkcja nigdy nie wracareturn (popupWindow.innerHeight > 0) === false;
. Funkcja zwraca false, gdy Twoja przeglądarka nie jest Chrome. Ponieważ onload jest procesem asynchronicznym. Twoja funkcja zwraca wartość false, a następnie wykonuje onload, ale wynik nigdy nie zwraca.Wypróbowałem wiele rozwiązań, ale jedynym, które mogłem wymyślić, które działało również z uBlock Origin, było wykorzystanie limitu czasu do sprawdzenia statusu zamkniętego wyskakującego okienka.
function popup (url, width, height) { const left = (window.screen.width / 2) - (width / 2) const top = (window.screen.height / 2) - (height / 2) let opener = window.open(url, '', `menubar=no, toolbar=no, status=no, resizable=yes, scrollbars=yes, width=${width},height=${height},top=${top},left=${left}`) window.setTimeout(() => { if (!opener || opener.closed || typeof opener.closed === 'undefined') { console.log('Not allowed...') // Do something here. } }, 1000) }
Oczywiście to hack; jak wszystkie rozwiązania tego problemu.
Musisz zapewnić wystarczająco dużo czasu w swoim setTimeout, aby uwzględnić początkowe otwarcie i zamknięcie, więc nigdy nie będzie dokładnie dokładne. Będzie to pozycja prób i błędów.
Dodaj to do swojej listy prób.
źródło
Prostym podejściem, jeśli posiadasz również kod potomny , byłoby utworzenie prostej zmiennej w jej html, jak poniżej:
<script> var magicNumber = 49; </script>
A następnie sprawdź jego istnienie od rodzica, coś podobnego do następującego:
// Create the window with login URL. let openedWindow = window.open(URL_HERE); // Check this magic number after some time, if it exists then your window exists setTimeout(() => { if (openedWindow["magicNumber"] !== 32) { console.error("Window open was blocked"); } }, 1500);
Czekamy chwilę, aby upewnić się, że strona została załadowana i sprawdzić, czy istnieje. Oczywiście, gdyby okno nie załadowało się po 1500 ms, zmienna nadal by była
undefined
.źródło
Korzystając ze zdarzenia onbeforeunload możemy sprawdzić w następujący sposób
otworzy 2 czarne okna w tle
funkcja zwraca wartość logiczną.
źródło