Bir tarayıcının pop-up'ı engellediğini nasıl tespit edebilirim?


130

Zaman zaman, yeni bir pencere açmaya çalışan (kullanıcı girişi veya önemli bir şey için) bir web sayfasına rastladım, ancak açılır pencere engelleyici bunun olmasını engelliyor.

Yeni pencerenin düzgün bir şekilde açıldığından emin olmak için arama penceresi hangi yöntemleri kullanabilir?

Yanıtlar:


160

Pop-up'ı açmak için JavaScript kullanıyorsanız, bunun gibi bir şey kullanabilirsiniz:

var newWin = window.open(url);             

if(!newWin || newWin.closed || typeof newWin.closed=='undefined') 
{ 
    //POPUP BLOCKED
}

İşte chrome için bir cevap: Detect-
block

@ajwaka, bu cevabın chrome için başarısız olup olmadığını lütfen açıklayabilir misiniz, yoksa diğer cevabın chrome için daha iyi olmasının bir nedeni var mı? Teşekkürler!
Crashalot

@ajwaka en azından bugün bu kod krom üzerinde çalışıyor gibi görünüyor, dolayısıyla soru.
Crashalot

@Crashalot - Bana 6 yıl önce cevapladığım bir şeyi soruyorsunuz - Maalesef durumu artık hatırlamıyorum ve tarayıcılar 6 yılda uzun bir yol kat etti.
ajwaka

40

Yukarıdaki birkaç örneği denedim, ancak Chrome ile çalışmasını sağlayamadım. Bu basit yaklaşım Chrome 39, Firefox 34, Safari 5.1.7 ve IE 11 ile çalışıyor gibi görünüyor. JS kitaplığımızdan kod parçacığı burada.

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.");
    }
}

1
@Surendra lütfen, "çalışmıyor" derken ne demek istediğini belirtebilir misin? Ayrıştırma zamanında bir hata mı? Çalışma zamanında bir hata mı var? Açılır pencere açılıyor ancak engellenmiş olarak işaretlenmiş mi? Açılır pencere engellenmiş ancak açık olarak işaretlenmiş mi? NULL üzerinde odak () çağrısına izin verilmediği sürece, gezginin neden başarısız olacağına dair herhangi bir neden görmüyorum, bu durumda denemeden önce NULL testi işe yarayacaktır.
FrancescoMM

IE, pop-up başarılı olsa bile her zaman boş döndürür.
Devin Garner

34

Güncelleme: Popup'lar gerçekten çok eski zamanlardan beri var. İlk fikir, ana pencereyi kapatmadan başka bir içerik göstermekti. Şu an itibariyle, bunu yapmanın başka yolları da var: JavaScript, sunucu için istek gönderebildiğinden, pop-up'lar nadiren kullanılır. Ama bazen hala kullanışlıdırlar.

Geçmişte kötü siteler, pop-up'ları çok kötüye kullandı. Kötü bir sayfa, reklamlarla birlikte tonlarca açılır pencere açabilir. Artık çoğu tarayıcı pop-up'ları engellemeye ve kullanıcıyı korumaya çalışıyor.

Çoğu tarayıcı, onclick gibi kullanıcı tarafından tetiklenen olay işleyicilerin dışında çağrılırsa açılır pencereleri engeller.

Düşünürseniz, bu biraz aldatıcıdır. Kod doğrudan bir onclick işleyicisindeyse, bu kolaydır. Peki setTimeout'ta açılır pencere nedir?

Bu kodu deneyin:

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

Pop-up Chrome'da açılıyor, ancak Firefox'ta engelleniyor.

… Ve bu Firefox'ta da çalışıyor:

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

Aradaki fark, Firefox'un 2000 ms veya daha az bir zaman aşımı olarak kabul edilebilir olmasıdır, ancak ondan sonra - artık "kullanıcı eyleminin dışında" olduğunu varsayarak "güveni" kaldırır. Yani birincisi bloke edilir, ikincisi bloke olmaz.


2012'de geçerli olan orijinal cevap:

Açılır pencere engelleyici kontrolü için bu çözüm FF (v11), Safari (v6), Chrome (v23.0.127.95) ve IE (v7 ve v9) 'da test edilmiştir. Hata mesajını uygun gördüğünüz şekilde işlemek için displayError işlevini güncelleyin.

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.");
    }
};

Kullanımı:

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

Bu yardımcı olur umarım! :)


20
Sanırım daha fazla alt çizgiye ihtiyacın var
Jacob Stamm

Firefox'ta bu, boş sayfayı görüntüler ve açıcı sayfadaki açılır pencere engelleyici mesajını bile göremezsiniz. Boş sayfa nasıl kapatılır?
user460114

Açılır pencere url'si indirilebilir bir dosya ise ( Content-Disposition: attachment;yanıt başlığında bulunur), açılır pencerenin hemen kapanacağını, bu nedenle setTimeoutkodun başarısız olacağını ve tarayıcının "Pop-up Engelleyicisinin etkinleştirildiğinden" şikayet edeceğini unutmayın. Chrome için @ DanielB'nin çözümünü öneriyorum ve harika çalışıyor.
wonsuc

1
@wonsuc Content-Disposition: attachment;başlığı olan bir bağlantıyı açarken açılır pencerede açmanıza gerek yoktur. İndirmek istediğiniz varlığa doğrudan bir bağlantı oluşturun ve tarayıcının yerel davranışı sizi geçerli sayfadan başka bir yere yönlendirmeden indirmenize izin verecektir.
Kevin B

@KevinB Belirli bir durumda olduğumu söylemeliyim. HTML'den PDF dosyaları oluşturan birden fazla dosya indirmem gerekiyor. Ve HTML içeriği büyükse, bazen birkaç saniye sürer ve window.locationbunun için kullanırsam , ilk dosyanın oluşturulması çok uzun sürerse, ikinci istek başladığında yok sayılır. Yanıtın ne zaman biteceğini bilmeme asla izin vermediğinden kullanmamın nedeni window.openbu window.location.
wonsuc

12

Tarayıcı şirketi veya sürümü ne olursa olsun her zaman işe yarayacak bir "çözüm" , ekrana, kontrole yakın bir yerde bir açılır pencere oluşturacak ve kullanıcıyı eylemin bir açılır pencere gerektirdiği konusunda kibarca uyaran bir uyarı mesajı koymaktır. lütfen bunları site için etkinleştirin.

Fantezi falan olmadığını biliyorum, ama daha basit olamaz ve sadece yaklaşık 5 dakikalık test gerektirir, o zaman diğer kabuslara geçebilirsiniz.

Kullanıcı, siteniz için pop-up'lara izin verdiğinde, pop-up'ları aşırıya kaçmamanız da dikkate alınacaktır. Yapmak isteyeceğiniz son şey ziyaretçilerinizi kızdırmaktır.


1
Ne yazık ki, bazen bu sorudaki diğer tüm çözümler kabul edilemez - sadece bu. Neden? Çünkü hepsi bir açılır pencere görüntülemeye çalışır - sadece açılır pencerelerin etkin olup olmadığını algılamakla kalmaz. Ya sessizce yapmak istersem?
Sagi Mann

Burada da hatırlanması gereken bir şey, bir kullanıcının siteniz için her zaman sadece pop-up'ları etkinleştiremeyeceğidir. Safari'nin eski sürümlerinde, örneğin, bir kullanıcı açılır pencere engelleyiciyi yalnızca tamamen etkinleştirebilir veya devre dışı bırakabilir, beyaz liste mevcut değildir.
Jeremy

1

@ Kevin B ve @ DanielB'nin çözümlerini birleştirdim.
Bu çok daha basit.

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

Kullanımı:

var popup = window.open('https://www.google.com', '_blank');
if (isPopupBlockerActivated(popup)) {
    // Do what you want.
}

1
isPopupBlockerActivated işlev asla geri dönmez return (popupWindow.innerHeight > 0) === false;. Tarayıcınız Chrome değilse, işleviniz yanlış döndürür. Çünkü onload asenkron bir süreçtir. İşleviniz yanlış döndürür ve sonra çalıştırılır ancak sonucu asla geri dönmez.
Onur Gazioğlu

0

Çok sayıda çözüm denedim, ancak bulabildiğim tek çözüm, uBlock Origin ile de çalıştı, açılır pencerenin kapalı durumunu kontrol etmek için bir zaman aşımı kullanmaktı.

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

Açıkçası bu bir hack; bu problemin tüm çözümleri gibi.

İlk açılış ve kapanışı hesaba katmak için setTimeout'unuzda yeterli zaman sağlamanız gerekir, böylece asla tam olarak doğru olmayacaktır. Bir deneme yanılma pozisyonu olacak.

Bunu denemeler listenize ekleyin.


0

Alt koda da sahipseniz basit bir yaklaşım , html'sinde aşağıdaki gibi basit bir değişken oluşturmak olacaktır:

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

Ve sonra varlığını ebeveynden aşağıdakine benzer bir şekilde kontrol edin:

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

Web sayfasının yüklendiğinden emin olmak ve varlığını kontrol etmek için bir süre bekleriz. Açıktır ki, pencere 1500 ms sonra yüklenmediyse, değişken yine de olacaktır undefined.


-1

Onbeforeunload olayını kullanarak aşağıdaki gibi kontrol edebiliriz

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

arka planda 2 siyah pencere açacak

işlev boole değerini döndürür.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.