Znam techniki javascript służące do wykrywania, czy wyskakujące okienko jest blokowane w innych przeglądarkach (jak opisano w odpowiedzi na to pytanie ). Oto podstawowy test:
var newWin = window.open(url);
if(!newWin || newWin.closed || typeof newWin.closed=='undefined')
{
//POPUP BLOCKED
}
Ale to nie działa w Chrome. Sekcja „POPUP BLOCKED” nie jest nigdy otwierana, gdy wyskakujące okienko jest zablokowane.
Oczywiście test działa do pewnego stopnia, ponieważ Chrome w rzeczywistości nie blokuje wyskakującego okienka, ale otwiera je w małym zminimalizowanym oknie w prawym dolnym rogu, które zawiera listę „zablokowanych” wyskakujących okienek.
Chciałbym móc stwierdzić, czy wyskakujące okienko zostało zablokowane przez moduł blokujący wyskakujące okienka Chrome. Staram się unikać podsłuchiwania przeglądarki na rzecz wykrywania funkcji. Czy można to zrobić bez węszenia przeglądarki?
Edit : Mam teraz próbował Wykorzystując newWin.outerHeight
, newWin.left
i inne podobne właściwości do osiągnięcia tego celu. Google Chrome zwraca wszystkie wartości pozycji i wysokości jako 0, gdy wyskakujące okienko jest zablokowane.
Niestety zwraca również te same wartości, nawet jeśli wyskakujące okienko jest faktycznie otwarte przez nieznany czas. Po pewnym magicznym okresie (kilka sekund w moich testach) informacje o lokalizacji i rozmiarze są zwracane jako prawidłowe wartości. Innymi słowy, nadal nie jestem bliżej rozwiązania tego problemu. Każda pomoc będzie mile widziana.
źródło
Odpowiedzi:
Cóż, "magiczny czas", o którym mówisz, jest prawdopodobnie wtedy, gdy zostanie załadowany DOM wyskakującego okienka. Albo może się tak zdarzyć, gdy wszystko (obrazy, zewnętrzny CSS itp.) Zostało załadowane. Możesz to łatwo przetestować, dodając bardzo dużą grafikę do wyskakującego okienka (najpierw wyczyść pamięć podręczną!). Jeśli używasz JavaScript Framework, takiego jak jQuery (lub coś podobnego), możesz użyć zdarzenia ready () (lub czegoś podobnego), aby poczekać na załadowanie DOM przed sprawdzeniem przesunięcia okna. Niebezpieczeństwo polega na tym, że wykrywanie Safari działa w sposób sprzeczny: DOM wyskakującego okienka nigdy nie będzie gotowy () w Safari, ponieważ da ci prawidłowy uchwyt dla okna, które próbujesz otworzyć - niezależnie od tego, czy faktycznie się otworzy, czy nie. (w rzeczywistości uważam, że powyższy kod testu wyskakującego okienka nie zadziała w przypadku safari).
Myślę, że najlepszą rzeczą, jaką możesz zrobić, jest zawinięcie testu w setTimeout () i pozostawienie wyskakującemu okienku 3-5 sekund na zakończenie ładowania przed uruchomieniem testu. Nie jest doskonały, ale powinien działać co najmniej w 95% przypadków.
Oto kod, którego używam do wykrywania w różnych przeglądarkach, bez części Chrome.
To, co robię, to uruchamianie tego testu od rodzica i zawijanie go w setTimeout (), dając okno podrzędne 3-5 sekund na załadowanie. W oknie podrzędnym musisz dodać funkcję testową:
test funkcji () {}
Detektor blokowania wyskakujących okienek sprawdza, czy funkcja „test” istnieje jako element składowy okna podrzędnego.
DODANO 15 CZERWCA 2015:
Myślę, że nowoczesnym sposobem radzenia sobie z tym byłoby użycie window.postMessage (), aby dziecko powiadomiło rodzica, że okno zostało załadowane. Podejście jest podobne (dziecko mówi rodzicowi, że jest załadowane), ale sposób komunikacji się poprawił. Mogłem zrobić to między domenami od dziecka:
Rodzic nasłuchuje tej wiadomości za pomocą:
Mam nadzieję że to pomoże.
źródło
Tylko jedno ulepszenie snipet'a InvisibleBacon (testowane w IE9, Safari 5, Chrome 9 i FF 3.6):
źródło
Poniżej przedstawiono rozwiązanie jQuery do sprawdzania blokowania wyskakujących okienek. Został przetestowany w FF (v11), Safari (v6), Chrome (v23.0.127.95) i IE (v7 i v9). Zaktualizuj funkcję _displayError, aby obsłużyć komunikat o błędzie według własnego uznania.
Stosowanie:
Mam nadzieję że to pomoże! :)
źródło
Odpowiedź Richa nie będzie już działać w Chrome. Wygląda na to, że Chrome faktycznie wykonuje teraz dowolny JavaScript w wyskakującym okienku. Skończyło się na sprawdzaniu wartości screenX równej 0, aby sprawdzić, czy nie ma zablokowanych wyskakujących okienek. Myślę też, że znalazłem sposób, aby zagwarantować, że ta nieruchomość jest ostateczna przed sprawdzeniem. Działa to tylko w przypadku wyskakujących okienek w Twojej domenie, ale możesz dodać moduł obsługi ładowania w następujący sposób:
Jak wielu informowało, właściwość „screenX” czasami zgłasza wartość niezerową w przypadku nieudanych wyskakujących okienek, nawet po załadowaniu. Doświadczyłem również tego zachowania, ale jeśli dodasz sprawdzenie po przekroczeniu limitu czasu równego zero ms, właściwość screenX zawsze wydaje się zwracać spójną wartość.
Daj mi znać, jeśli istnieją sposoby na ulepszenie tego skryptu. Wydaje się, że działa to dla moich celów.
źródło
onload
nigdy nie strzela.To zadziałało dla mnie:
Zewnętrzna wysokość i zewnętrzna szerokość dotyczą chromu, ponieważ sztuczka „about: blank” z góry nie działa już w przypadku chromu.
źródło
Mam zamiar po prostu skopiować / wkleić podaną tutaj odpowiedź: https://stackoverflow.com/a/27725432/892099 przez DanielB. działa na chrome 40 i jest bardzo czysty. nie ma brudnych hacków ani czekania.
źródło
Co powiesz na
Promise
podejście?I możesz go używać jak klasycznego
window.open
Możesz zmienić kod tak, aby nie spełniał obietnicy zamiast zwracać
undefined
, po prostu pomyślałem, żeif
to łatwiejszy przepływ sterowania niżtry / catch
w tym przypadku.źródło
Sprawdź położenie okna względem rodzica. Chrome sprawia, że okno pojawia się prawie poza ekranem.
źródło
Miałem podobny problem z wyskakującymi okienkami, które nie otwierały się w Chrome. Byłem sfrustrowany, ponieważ nie próbowałem zrobić czegoś podstępnego, na przykład wyskakującego okienka ładowania, po prostu otwierając okno, gdy użytkownik kliknął. Byłem PODWÓJNIE sfrustrowany, ponieważ uruchomienie funkcji obejmującej window.open () z wiersza poleceń firebug działało, podczas gdy kliknięcie mojego łącza nie działało! Oto moje rozwiązanie:
Niepoprawny sposób: uruchamianie window.open () z detektora zdarzeń (w moim przypadku dojo.connect z metodą zdarzenia onclick węzła DOM).
Właściwy sposób: przypisanie funkcji do właściwości onclick węzła, który wywołał window.open ().
Oczywiście, jeśli zajdzie taka potrzeba, nadal mogę obsługiwać detektory zdarzeń dla tego samego zdarzenia onclick. Dzięki tej zmianie mogłem otwierać okna, mimo że Chrome było ustawione na „Nie zezwalaj żadnej witrynie na pokazywanie wyskakujących okienek”. Radość.
Jeśli ktoś mądry w Chrome może powiedzieć reszcie z nas, dlaczego to robi różnicę, chciałbym to usłyszeć, chociaż podejrzewam, że to tylko próba zamknięcia drzwi przed złośliwymi programowymi wyskakującymi okienkami.
źródło
Oto wersja, która obecnie działa w przeglądarce Chrome. Tylko mała zmiana w stosunku do rozwiązania Richa, chociaż dodałem w opakowaniu, które również obsługuje synchronizację.
Aby go użyć, po prostu zrób to:
Jeśli wyskakujące okienko zostanie zablokowane, komunikat ostrzegawczy pojawi się po 5 sekundach okresu karencji (możesz to zmienić, ale 5 sekund powinno być całkiem bezpieczne).
źródło
Ten fragment zawiera wszystkie powyższe - z jakiegoś powodu - StackOverflow wyklucza pierwszą i ostatnią linię kodu w poniższym bloku kodu, więc napisałem o tym blog. Pełne wyjaśnienie i resztę (do pobrania) kodu można znaleźć na moim blogu pod adresem thecodeabode.blogspot.com
źródło
Wow, na pewno jest tu wiele rozwiązań. To jest moje, wykorzystuje rozwiązania wzięte z aktualnej akceptowanej odpowiedzi (która nie działa w najnowszym Chrome i wymaga zawijania go w timeout), a także powiązane rozwiązanie w tym wątku (który jest właściwie waniliowym JS, a nie jQuery) .
Mój używa architektury wywołania zwrotnego, która zostanie wysłana,
true
gdy wyskakujące okienko zostanie zablokowane lub wfalse
inny sposób.źródło
Odpowiedź Jasona to jedyna metoda, o której również przychodzi mi do głowy, ale poleganie na takiej pozycji jest trochę podejrzane!
W dzisiejszych czasach tak naprawdę nie musisz zadawać pytania „czy moje niechciane wyskakujące okienka zostały zablokowane?”, Ponieważ odpowiedź zawsze brzmi „tak” - wszystkie główne przeglądarki mają domyślnie włączoną funkcję blokowania wyskakujących okienek. Najlepszym podejściem jest użycie metody window.open () w odpowiedzi na bezpośrednie kliknięcie, co prawie zawsze jest dozwolone.
źródło
CZEŚĆ
Zmodyfikowałem nieco rozwiązania opisane powyżej i uważam, że działa przynajmniej pod Chrome. Moje rozwiązanie ma na celu wykrycie, czy wyskakujące okienko jest blokowane po otwarciu strony głównej, a nie po otwarciu wyskakującego okienka, ale jestem pewien, że są osoby, które mogą je modyfikować. :-) Wadą jest to, że wyświetlane jest wyskakujące okienko przez kilka sekund (może być możliwe trochę skrócenie), gdy nie ma programu blokującego wyskakujące okienka.
Umieściłem to w sekcji mojego „głównego” okna
Wyskakujący test wygląda następująco:
Gdy wywołuję funkcję test na stronie wyskakującej po 3500 ms, wewnętrzna wysokość została poprawnie ustawiona przez Chrome.
Używam zmiennej popUpsBlocked, aby wiedzieć, czy wyskakujące okienka są wyświetlane, czy nie w innych skryptach JavaScript. to znaczy
źródło
źródło
O ile wiem (z tego, co przetestowałem), Chrome zwraca obiekt okna z lokalizacją „about: blank”. Tak więc następujące elementy powinny działać we wszystkich przeglądarkach:
źródło