ฉันจะตรวจสอบได้อย่างไรว่าเบราว์เซอร์บล็อกป๊อปอัป


130

บางครั้งฉันเจอหน้าเว็บที่พยายามเปิดหน้าต่างใหม่ขึ้นมา (สำหรับการป้อนข้อมูลของผู้ใช้หรือสิ่งที่สำคัญ) แต่ตัวป้องกันป๊อปอัปจะป้องกันไม่ให้สิ่งนี้เกิดขึ้น

หน้าต่างการโทรสามารถใช้วิธีใดเพื่อให้แน่ใจว่าหน้าต่างใหม่เปิดอย่างถูกต้อง

คำตอบ:


160

หากคุณใช้ JavaScript เพื่อเปิดป๊อปอัปคุณสามารถใช้สิ่งต่อไปนี้:

var newWin = window.open(url);             

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

นี่คือคำตอบสำหรับ chrome: detect-
block

@ajwaka คุณช่วยชี้แจงได้ไหมว่าคำตอบนี้ล้มเหลวสำหรับ chrome หรือมีเหตุผลที่คำตอบอื่นดีกว่าสำหรับ chrome? ขอบคุณ!
Crashalot

@ajwaka อย่างน้อยวันนี้รหัสนี้ดูเหมือนจะใช้งานได้กับ chrome ดังนั้นคำถาม
Crashalot

@Crashalot - คุณกำลังถามฉันเกี่ยวกับสิ่งที่ฉันตอบเมื่อ 6 ปีที่แล้ว - ฉันเสียใจที่จำสถานการณ์ไม่ได้อีกต่อไปและเบราว์เซอร์มีมานานแล้วในรอบ 6 ปี
Ajwaka

40

ฉันลองหลายตัวอย่างข้างต้นแล้ว แต่ไม่สามารถทำให้มันทำงานกับ Chrome ได้ วิธีง่ายๆนี้ดูเหมือนจะใช้ได้กับ Chrome 39, Firefox 34, Safari 5.1.7 และ IE 11 นี่คือตัวอย่างโค้ดจากไลบรารี JS ของเรา

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 ช่วยระบุคำว่า "ไม่ทำงาน" ได้ไหม ข้อผิดพลาดในการแยกวิเคราะห์เวลา? เกิดข้อผิดพลาดขณะรันไทม์? ป๊อปอัปเปิดขึ้น แต่ถูกทำเครื่องหมายว่าถูกบล็อก? ป๊อปอัปถูกบล็อก แต่ถูกทำเครื่องหมายว่าเปิดอยู่? ฉันไม่เห็นเหตุผลใด ๆ ว่าทำไม explorer ถึงล้มเหลวในกรณีนี้เว้นแต่จะอนุญาตให้เรียก focus () บน NULL ในกรณีนี้การทดสอบค่า NULL ก่อนที่จะลองใช้งานได้
FrancescoMM

IE ส่งคืนค่าว่างเสมอแม้ว่าป๊อปอัปจะสำเร็จก็ตาม
Devin Garner

34

อัปเดต: ป๊อปอัปมีมาตั้งแต่สมัยโบราณจริงๆ แนวคิดเริ่มต้นคือการแสดงเนื้อหาอื่นโดยไม่ต้องปิดหน้าต่างหลัก ณ ตอนนี้มีวิธีอื่นในการทำเช่นนั้น: JavaScript สามารถส่งคำขอสำหรับเซิร์ฟเวอร์ได้ดังนั้นจึงไม่ค่อยมีการใช้ป๊อปอัป แต่บางครั้งก็ยังสะดวก

ในอดีตไซต์ที่ชั่วร้ายมีการละเมิดป๊อปอัปเป็นจำนวนมาก หน้าเว็บที่ไม่ดีอาจเปิดหน้าต่างป๊อปอัปจำนวนมากพร้อมโฆษณา ตอนนี้เบราว์เซอร์ส่วนใหญ่จึงพยายามบล็อกป๊อปอัปและปกป้องผู้ใช้

เบราว์เซอร์ส่วนใหญ่จะบล็อกป๊อปอัปหากมีการเรียกใช้ภายนอกตัวจัดการเหตุการณ์ที่เรียกโดยผู้ใช้เช่น onclick

ถ้าคุณคิดว่ามันเป็นเรื่องยากสักหน่อย หากรหัสอยู่ในตัวจัดการ onclick โดยตรงนั่นเป็นเรื่องง่าย แต่ป๊อปอัปที่เปิดขึ้นใน setTimeout คืออะไร?

ลองใช้รหัสนี้:

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

ป๊อปอัปจะเปิดขึ้นใน Chrome แต่ถูกบล็อกใน Firefox

…และใช้งานได้ใน Firefox ด้วย:

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

ความแตกต่างก็คือ Firefox ถือว่าการหมดเวลา 2,000 มิลลิวินาทีหรือน้อยกว่านั้นเป็นสิ่งที่ยอมรับได้ แต่หลังจากนั้นจะลบ "ความไว้วางใจ" ออกโดยสมมติว่าตอนนี้ "อยู่นอกเหนือการดำเนินการของผู้ใช้" ดังนั้นอันแรกจึงถูกบล็อกและอันที่สองไม่ถูกบล็อก


คำตอบเดิมซึ่งเป็นปี 2012 ปัจจุบัน:

โซลูชันนี้สำหรับการตรวจสอบตัวบล็อกป๊อปอัปได้รับการทดสอบใน FF (v11), Safari (v6), Chrome (v23.0.127.95) และ IE (v7 & v9) อัปเดตฟังก์ชัน displayError เพื่อจัดการกับข้อความแสดงข้อผิดพลาดตามที่เห็นสมควร

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

การใช้งาน:

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

หวังว่านี่จะช่วยได้! :)


20
ฉันคิดว่าคุณต้องการขีดล่างมากกว่านี้
Jacob Stamm

ใน firefox จะแสดงหน้าว่างและคุณจะไม่เห็นข้อความตัวป้องกันป๊อปอัปในหน้าตัวเปิด จะปิดหน้าว่างได้อย่างไร?
user460114

โปรดทราบว่าหาก URL ของป๊อปอัปเป็นไฟล์ที่ดาวน์โหลดได้ (ซึ่งมีContent-Disposition: attachment;อยู่ในส่วนหัวของการตอบกลับ) ป๊อปอัปจะปิดทันทีดังนั้นsetTimeoutโค้ดจะล้มเหลวและเบราว์เซอร์จะบ่นว่า "เปิดใช้งาน Popup Blocker แล้ว!" สำหรับ Chrome ฉันขอแนะนำโซลูชันของ @ DanielB และใช้งานได้ดี
wonsuc

1
@wonsuc เมื่อเปิดลิงก์ที่มีContent-Disposition: attachment;ส่วนหัวคุณไม่จำเป็นต้องเปิดในป๊อปอัป เพียงแค่สร้างลิงก์โดยตรงไปยังเนื้อหาที่คุณต้องการดาวน์โหลดและพฤติกรรมดั้งเดิมของเบราว์เซอร์จะช่วยให้คุณสามารถดาวน์โหลดได้โดยไม่ต้องเปลี่ยนเส้นทางคุณออกจากหน้าปัจจุบัน
Kevin B

@KevinB ฉันต้องบอกว่าฉันอยู่ในสถานการณ์ที่เฉพาะเจาะจง ฉันต้องดาวน์โหลดไฟล์หลายไฟล์ซึ่งสร้างไฟล์ PDF จาก HTML และถ้าเนื้อหา HTML มีขนาดใหญ่บางครั้งอาจใช้เวลาหลายวินาทีและถ้าฉันใช้window.locationมันหากไฟล์แรกใช้เวลาสร้างนานเกินไปไฟล์นั้นจะถูกละเว้นเมื่อคำขอที่สองเริ่มต้นขึ้น นั่นคือเหตุผลที่ฉันต้องใช้window.openเนื่องจากwindow.locationไม่เคยแจ้งให้ฉันทราบเมื่อการตอบสนองเสร็จสิ้น
wonsuc

12

"วิธีแก้ปัญหา" อย่างหนึ่งที่จะใช้งานได้ตลอดเวลาไม่ว่าจะเป็นบริษัท เบราว์เซอร์หรือเวอร์ชันใดก็ตามคือเพียงแค่ใส่ข้อความเตือนบนหน้าจอซึ่งอยู่ใกล้กับส่วนควบคุมที่จะสร้างป๊อปอัปซึ่งจะเตือนผู้ใช้อย่างสุภาพว่าการดำเนินการนั้นต้องมีป๊อปอัป ขึ้นและโปรดเปิดใช้งานสำหรับไซต์

ฉันรู้ว่ามันไม่ได้หรูหราหรืออะไรเลย แต่มันไม่ง่ายไปกว่านี้และต้องใช้เวลาทดสอบประมาณ 5 นาทีเท่านั้นจากนั้นคุณก็จะไปสู่ฝันร้ายอื่น ๆ ได้

เมื่อผู้ใช้อนุญาตให้มีป๊อปอัปสำหรับไซต์ของคุณแล้วก็ควรพิจารณาหากคุณไม่ใช้ป๊อปอัปมากเกินไป สิ่งสุดท้ายที่คุณต้องการทำคือรบกวนผู้เยี่ยมชมของคุณ


1
น่าเสียดายที่บางครั้งวิธีแก้ปัญหาอื่น ๆ ทั้งหมดในคำถามนี้ไม่สามารถยอมรับได้มีเพียงวิธีนี้ ทำไม? เนื่องจากพวกเขาทั้งหมดพยายามแสดงป๊อปอัปไม่ใช่แค่ตรวจสอบว่าเปิดใช้งานป๊อปอัปหรือไม่ ถ้าอยากทำแบบเงียบ ๆ จะทำอย่างไร?
Sagi Mann

สิ่งที่ต้องจำไว้ที่นี่เช่นกันคือผู้ใช้ไม่สามารถเปิดใช้งานป๊อปอัปสำหรับไซต์ของคุณได้เสมอไป ตัวอย่างเช่นใน Safari เวอร์ชันเก่าผู้ใช้สามารถเปิดหรือปิดใช้งานตัวป้องกันป๊อปอัปได้ทั้งหมดเท่านั้นไม่มีรายการที่อนุญาตพิเศษ
Jeremy

1

ฉันรวมโซลูชันของ @Kevin B และ @ DanielB เข้าด้วยกัน
สิ่งนี้ง่ายกว่ามาก

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

การใช้งาน:

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

1
isPopupBlockerActivated return (popupWindow.innerHeight > 0) === false;ฟังก์ชั่นไม่เคยส่งกลับใน ฟังก์ชันคุณส่งคืนเท็จเมื่อเบราว์เซอร์ของคุณไม่ใช่ Chrome เนื่องจาก onload เป็นกระบวนการแบบอะซิงโครนัส ฟังก์ชั่นของคุณส่งคืนเท็จและจากนั้นดำเนินการ onload แต่ผลลัพธ์ไม่ส่งกลับ
Onur Gazioğlu

0

ฉันได้ลองใช้วิธีแก้ปัญหามากมาย แต่สิ่งเดียวที่ฉันสามารถหาได้ซึ่งทำงานร่วมกับ uBlock Origin ได้คือการใช้การหมดเวลาเพื่อตรวจสอบสถานะปิดของป๊อปอัป

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

เห็นได้ชัดว่านี่คือการแฮ็ก เช่นเดียวกับวิธีแก้ปัญหานี้ทั้งหมด

คุณต้องให้เวลาใน setTimeout เพียงพอสำหรับการเปิดและปิดครั้งแรกดังนั้นการเปิดและปิดครั้งแรกจะไม่ถูกต้องอย่างทั่วถึง มันจะเป็นตำแหน่งของการลองผิดลองถูก

เพิ่มสิ่งนี้ในรายการความพยายามของคุณ


0

วิธีง่ายๆหากคุณเป็นเจ้าของรหัสลูกเช่นกันคือการสร้างตัวแปรง่ายๆใน html ดังต่อไปนี้:

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

จากนั้นตรวจสอบการมีอยู่จากผู้ปกครองสิ่งที่คล้ายกับต่อไปนี้:

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

เรารอสักครู่เพื่อให้แน่ใจว่าได้โหลดหน้าเว็บแล้วและตรวจสอบการมีอยู่จริง เห็นได้ชัดว่าถ้าหน้าต่างไม่ได้โหลดหลังจาก 1500ms undefinedแล้วตัวแปรจะยังคงเป็น


-1

โดยใช้เหตุการณ์ onbeforeunload เราสามารถตรวจสอบได้ดังนี้

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

มันจะเปิดหน้าต่างสีดำ 2 บานเป็นพื้นหลัง

ฟังก์ชันส่งคืนค่าบูลีน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.