Bagaimana saya bisa mendeteksi jika browser memblokir popup?

130

Kadang-kadang, saya menemukan halaman web yang mencoba membuka jendela baru (untuk input pengguna, atau sesuatu yang penting), tetapi pemblokir popup mencegah hal ini terjadi.

Metode apa yang dapat digunakan jendela panggilan untuk memastikan jendela baru diluncurkan dengan benar?

Nathan Bedford
sumber

Jawaban:

160

Jika Anda menggunakan JavaScript untuk membuka sembulan, Anda dapat menggunakan sesuatu seperti ini:

var newWin = window.open(url);             

if(!newWin || newWin.closed || typeof newWin.closed=='undefined') 
{ 
    //POPUP BLOCKED
}
omar
sumber
Inilah jawaban untuk chrome: detect-blocked-popup-in-chrome
ajwaka
@ajwaka bisakah Anda menjelaskan jika jawaban ini gagal untuk chrome, atau adakah alasan jawaban lain lebih baik untuk chrome? Terima kasih!
Crashalot
@ajwaka setidaknya hari ini kode ini tampaknya berfungsi pada chrome, maka pertanyaannya.
Crashalot
@ Crashalot - Anda bertanya kepada saya tentang sesuatu yang saya jawab 6 tahun lalu - Sayangnya saya tidak lagi mengingat situasi dan browser telah berjalan jauh dalam 6 tahun.
ajwaka
40

Saya mencoba beberapa contoh di atas, tetapi saya tidak bisa membuatnya bekerja dengan Chrome. Pendekatan sederhana ini tampaknya bekerja dengan Chrome 39, Firefox 34, Safari 5.1.7, dan IE 11. Ini adalah potongan kode dari perpustakaan JS kami.

openPopUp: function(urlToOpen) {
    var popup_window=window.open(urlToOpen,"myWindow","toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, copyhistory=yes, width=400, height=400");            
    try {
        popup_window.focus();   
    } catch (e) {
        alert("Pop-up Blocker is enabled! Please add this site to your exception list.");
    }
}
DanielB
sumber
1
@Surendra tolong, bisakah Anda menentukan apa yang Anda maksud dengan "tidak bekerja"? Kesalahan pada saat parse? Kesalahan saat runtime? Munculan terbuka tetapi ditandai sebagai diblokir? Munculan diblokir tetapi ditandai sebagai terbuka? Saya tidak melihat alasan mengapa penjelajah akan gagal, kecuali memanggil fokus () pada NULL dalam hal ini, tes untuk NULL sebelum percobaan hanya akan berhasil.
FrancescoMM
IE selalu mengembalikan null, bahkan jika popup berhasil.
Devin Garner
34

Pembaruan: Popup ada dari zaman yang sangat kuno. Gagasan awal adalah menampilkan konten lain tanpa menutup jendela utama. Sampai sekarang, ada cara lain untuk melakukan itu: JavaScript dapat mengirim permintaan ke server, sehingga popup jarang digunakan. Namun terkadang mereka masih berguna.

Di masa lalu situs jahat popups banyak disalahgunakan. Halaman yang buruk bisa membuka banyak jendela sembul dengan iklan. Jadi sekarang sebagian besar peramban mencoba memblokir popup dan melindungi pengguna.

Sebagian besar browser memblokir popup jika mereka dipanggil di luar event handler yang dipicu pengguna seperti onclick.

Jika Anda memikirkannya, itu agak sulit. Jika kodenya secara langsung ada di handler onclick, maka itu mudah. Tetapi popup apa yang terbuka di setTimeout?

Coba kode ini:

 // open after 3 seconds
setTimeout(() => window.open('http://google.com'), 3000);

Munculan terbuka di Chrome, tetapi diblokir di Firefox.

... Dan ini juga berfungsi di Firefox:

 // open after 1 seconds
setTimeout(() => window.open('http://google.com'), 1000);

Perbedaannya adalah bahwa Firefox memperlakukan batas waktu 2000 ms atau kurang dapat diterima, tetapi setelah itu - menghapus "kepercayaan", dengan asumsi bahwa sekarang ini "di luar tindakan pengguna". Jadi yang pertama diblokir, dan yang kedua tidak.


Jawaban asli yang terkini 2012:

Solusi ini untuk memeriksa pemblokir popup telah diuji dalam FF (v11), Safari (v6), Chrome (v23.0.127.95) & IE (v7 & v9). Perbarui fungsi displayError untuk menangani pesan kesalahan yang Anda inginkan.

var popupBlockerChecker = {
    check: function(popup_window){
        var scope = this;
        if (popup_window) {
            if(/chrome/.test(navigator.userAgent.toLowerCase())){
                setTimeout(function () {
                    scope.is_popup_blocked(scope, popup_window);
                },200);
            }else{
                popup_window.onload = function () {
                    scope.is_popup_blocked(scope, popup_window);
                };
            }
        } else {
            scope.displayError();
        }
    },
    is_popup_blocked: function(scope, popup_window){
        if ((popup_window.innerHeight > 0)==false){ 
            scope.displayError();
        }
    },
    displayError: function(){
       alert("Popup Blocker is enabled! Please add this site to your exception list.");
    }
};

Pemakaian:

var popup = window.open("http://www.google.ca", '_blank');
popupBlockerChecker.check(popup);

Semoga ini membantu! :)

Kevin B
sumber
20
Saya pikir Anda perlu lebih banyak garis bawah
Jacob Stamm
Di firefox, ini menampilkan halaman kosong dan Anda bahkan tidak bisa melihat pesan pemblokir popup pada halaman pembuka. Bagaimana cara menutup halaman kosong?
user460114
Perhatikan bahwa jika popup url adalah file yang dapat diunduh (yang ada Content-Disposition: attachment;di header respons), popup akan segera ditutup, karena itu setTimeoutkode akan gagal, dan browser akan mengeluh bahwa "Pemblokir Popup diaktifkan!". Untuk Chrome, saya merekomendasikan solusi @ DanielB dan ini berfungsi dengan baik.
wonsuc
1
@wonsuc saat membuka tautan yang memiliki Content-Disposition: attachment;tajuk, Anda tidak perlu membukanya di sembulan. Cukup buat tautan langsung ke aset yang ingin Anda unduh dan perilaku asli browser akan memungkinkan Anda untuk mengunduh tanpa mengarahkan Anda menjauh dari halaman saat ini.
Kevin B
@ KevinB Saya harus mengatakan bahwa saya berada dalam situasi tertentu. Saya harus mengunduh banyak file yang menghasilkan file PDF dari HTML. Dan jika konten HTML besar, kadang-kadang butuh beberapa detik dan jika saya gunakan window.locationuntuk itu, jika file pertama terlalu lama untuk menghasilkan, itu akan diabaikan ketika permintaan kedua dimulai. Itulah alasan mengapa saya harus menggunakan window.open, karena window.locationtidak pernah memberi tahu saya ketika respons selesai.
wonsuc
12

Salah satu "solusi" yang akan selalu berfungsi terlepas dari perusahaan atau versi peramban adalah dengan cukup menaruh pesan peringatan di layar, di suatu tempat dekat dengan kontrol yang akan membuat pop-up, yang dengan sopan memperingatkan pengguna bahwa tindakan memerlukan pop-up dan untuk mengaktifkannya untuk situs tersebut.

Saya tahu ini tidak mewah atau apa pun, tetapi tidak bisa lebih sederhana dan hanya membutuhkan sekitar 5 menit pengujian, maka Anda dapat beralih ke mimpi buruk lainnya.

Setelah pengguna mengizinkan pop-up untuk situs Anda, itu juga akan menjadi pertimbangan jika Anda tidak berlebihan pop-up. Hal terakhir yang ingin Anda lakukan adalah mengganggu pengunjung Anda.

Tidak ada
sumber
1
Sayangnya, terkadang semua solusi lain dalam pertanyaan ini tidak dapat diterima - hanya yang ini. Mengapa? Karena mereka semua mencoba untuk menampilkan popup - tidak hanya mendeteksi jika popup diaktifkan. Bagaimana jika saya ingin melakukannya secara diam-diam?
Sagi Mann
Yang juga perlu diingat di sini adalah bahwa pengguna tidak selalu dapat mengaktifkan sembulan untuk situs Anda. Dalam safari versi lama misalnya, pengguna hanya dapat mengaktifkan atau menonaktifkan pemblokir popup sepenuhnya, tidak ada daftar putih yang tersedia.
Jeremy
1

Saya menggabungkan solusi @Kevin B dan @ DanielB.
Ini jauh lebih sederhana.

var isPopupBlockerActivated = function(popupWindow) {
    if (popupWindow) {
        if (/chrome/.test(navigator.userAgent.toLowerCase())) {
            try {
                popupWindow.focus();
            } catch (e) {
                return true;
            }
        } else {
            popupWindow.onload = function() {
                return (popupWindow.innerHeight > 0) === false;
            };
        }
    } else {
        return true;
    }
    return false;
};

Pemakaian:

var popup = window.open('https://www.google.com', '_blank');
if (isPopupBlockerActivated(popup)) {
    // Do what you want.
}
wonsuc
sumber
1
isPopupBlockerActivated fungsi tidak pernah kembali aktif return (popupWindow.innerHeight > 0) === false;. Anda berfungsi mengembalikan false ketika browser Anda bukan Chrome. Karena onload adalah proses asinkron. Fungsi Anda mengembalikan false dan kemudian memuat dijalankan, tetapi hasilnya tidak pernah kembali.
Onur Gazioğlu
0

Saya sudah mencoba banyak solusi, tetapi satu-satunya yang bisa saya gunakan yang juga bekerja dengan uBlock Origin, adalah dengan menggunakan batas waktu untuk memeriksa status popup yang tertutup.

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)
}

Jelas ini adalah hack; seperti semua solusi untuk masalah ini.

Anda perlu menyediakan waktu yang cukup di setTimeout Anda untuk memperhitungkan pembukaan dan penutupan awal, sehingga tidak akan pernah sepenuhnya akurat. Ini akan menjadi posisi coba-coba.

Tambahkan ini ke daftar upaya Anda.

Michael Giovanni Pumo
sumber
0

Pendekatan sederhana jika Anda memiliki kode anak juga, akan membuat variabel sederhana dalam html-nya seperti di bawah ini:

    <script>
        var magicNumber = 49;
    </script>

Dan kemudian periksa keberadaannya dari induknya sesuatu yang mirip dengan berikut:

    // 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);

Kami menunggu beberapa saat untuk memastikan bahwa halaman web telah dimuat, dan memeriksa keberadaannya. Jelas, jika jendela tidak memuat setelah 1500ms maka variabel akan tetap undefined.

Lalit Umbarkar
sumber
-1

Dengan menggunakan onbeforeunload acara, kami dapat memeriksa sebagai berikut

    function popup()
    {
        var chk=false;
        var win1=window.open();
        win1.onbeforeunload=()=>{
            var win2=window.open();
            win2.onbeforeunload=()=>{
                chk=true;
            };
        win2.close();
        };
        win1.close();
        return chk;
    }

itu akan membuka 2 jendela hitam di latar belakang

fungsi mengembalikan nilai boolean.

Yash Bora
sumber