ป้องกันไม่ให้หน้าเว็บนำทางออกไปโดยใช้ JavaScript


130

จะป้องกันไม่ให้หน้าเว็บออกไปโดยใช้ JavaScript ได้อย่างไร?


อะไรทำให้หน้านี้นำทางไป
Niyaz

9
ตามคำถาม JavaScript ทำให้มันหายไป ...
Shog9


@ Shog9 มันอาจจะปิดแท็บทำให้มันออกไป นิ้วชี้ของฉันทำท่า ...
Bob Stein

คำตอบ:


160

การใช้onunloadช่วยให้คุณสามารถแสดงข้อความ แต่จะไม่รบกวนการนำทาง (เพราะสายเกินไป) อย่างไรก็ตามการใช้onbeforeunloadจะขัดจังหวะการนำทาง:

window.onbeforeunload = function() {
  return "";
}

หมายเหตุ: สตริงว่างจะถูกส่งคืนเนื่องจากเบราว์เซอร์รุ่นใหม่ให้ข้อความเช่น "การเปลี่ยนแปลงที่ไม่ได้บันทึกจะสูญหาย" ซึ่งไม่สามารถลบล้างได้

ในเบราว์เซอร์รุ่นเก่าคุณสามารถระบุข้อความที่จะแสดงในพรอมต์:

window.onbeforeunload = function() {
  return "Are you sure you want to navigate away?";
}

11
เบราว์เซอร์จะแสดงข้อความแจ้งที่เหมาะสม แค่ใช้window.onbeforeunload = function() { return ""; }
KIM Taegyoon

แต่นั่นยังไม่เพียงพอ สิ่งที่เกี่ยวกับการควบคุมภายในแบบฟอร์ม? พวกเขาเรียกสิ่งนี้ด้วย
Fandango68

1
เบราว์เซอร์สมัยใหม่ไม่อนุญาตให้คุณแสดงข้อความที่กำหนดเองในข้อความแจ้งเนื่องจากสิ่งนี้ถูกละเมิดโดยฟิชเชอร์และสิ่งที่คล้ายกัน
Flimm

ขอบคุณ @Flimm ฉันได้อัปเดตคำตอบเพื่อให้ถูกต้องสำหรับเบราว์เซอร์ปัจจุบัน
Jimmie R. Houts

@Flimm ฉันต้องการอัปเดตสถานะออนไลน์ของผู้ใช้เมื่อผู้ใช้ออนไลน์ปิดแท็บเบราว์เซอร์หรือเบราว์เซอร์ฉันใช้รหัสในโซลูชัน แต่ไม่ได้ผลมีวิธีแก้ปัญหานี้หรือไม่?
Nasimba

23

ซึ่งแตกต่างจากวิธีการอื่น ๆ ที่นำเสนอที่นี่รหัสบิตนี้จะไม่ทำให้เบราว์เซอร์แสดงคำเตือนเพื่อถามผู้ใช้ว่าต้องการออกหรือไม่ แทนที่จะใช้ประโยชน์จากลักษณะเหตุการณ์ของ DOM เพื่อเปลี่ยนเส้นทางกลับไปยังหน้าปัจจุบัน (และยกเลิกการนำทาง) ก่อนที่เบราว์เซอร์จะมีโอกาสยกเลิกการโหลดจากหน่วยความจำ

เนื่องจากมันทำงานโดยการนำทางลัดวงจรโดยตรงจึงไม่สามารถใช้เพื่อป้องกันไม่ให้ปิดเพจได้ อย่างไรก็ตามสามารถใช้เพื่อปิดใช้งานการป้องกันเฟรม

(function () {
    var location = window.document.location;

    var preventNavigation = function () {
        var originalHashValue = location.hash;

        window.setTimeout(function () {
            location.hash = 'preventNavigation' + ~~ (9999 * Math.random());
            location.hash = originalHashValue;
        }, 0);
    };

    window.addEventListener('beforeunload', preventNavigation, false);
    window.addEventListener('unload', preventNavigation, false);
})();

คำเตือน:คุณไม่ควรทำเช่นนี้ หากหน้าเว็บมีรหัสป้องกันเฟรมโปรดเคารพความปรารถนาของผู้เขียน


แสดงกิริยาอย่างไรหากผู้ใช้ต้องการปิดเบราว์เซอร์ (คลิกที่ปิด) มันจริงเหรอ?

15

ฉันลงเอยด้วยเวอร์ชันที่แตกต่างกันเล็กน้อยนี้:

var dirty = false;
window.onbeforeunload = function() {
    return dirty ? "If you leave this page you will lose your unsaved changes." : null;
}

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

ด้วยข้อความในคำตอบที่เลือกคุณจะเห็นข้อความแจ้งซ้ำซ้อน:

ใส่คำอธิบายภาพที่นี่


3
ใน IE ถ้าสกปรกเป็นเท็จสตริง 'null' จะแสดงขึ้น เพียงห่อไว้ในคำสั่ง if ดู: stackoverflow.com/questions/11793996/…
Jacob van Lingen

เห็นด้วย @JacobvanLingen นี่จะเป็นคำตอบที่ดีที่สุดที่นี่และสำหรับคำถามอื่น ๆ อีกสาม ข้อถ้ามันจบลงด้วยแทนที่จะเป็นโมฆะ (1) เป็นเงื่อนไข (2) กล่าวถึง "สกปรก" ซึ่งเป็นเหตุผลที่ถูกต้องที่สุดในการขัดขวางการนำทางและ (3) มีภาพหน้าจอ undefined
Bob Stein

สิ่งนี้จะใช้ได้กับทุกเบราว์เซอร์หรือไม่ถ้ามันลงท้ายด้วย undefined แทนที่จะเป็น null
อันตราย

9

เทียบเท่าในรูปแบบที่ทันสมัยกว่าและเข้ากันได้กับเบราว์เซอร์โดยใช้ addEventListener API ที่ทันสมัย

window.addEventListener('beforeunload', (event) => {
  // Cancel the event as stated by the standard.
  event.preventDefault();
  // Chrome requires returnValue to be set.
  event.returnValue = '';
});

ที่มา: https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload


1
อย่าลืมใช้ตัวพิมพ์ใหญ่ให้ถูกต้องevent.returnValue
Flimm

7

ในตัวอย่างของ Ayman โดยการส่งคืนเท็จคุณจะป้องกันไม่ให้หน้าต่าง / แท็บเบราว์เซอร์ปิด

window.onunload = function () {
  alert('You are trying to leave.');
  return false;
}

2
เว้นแต่ว่าเบราว์เซอร์เป็น Opera ซึ่งจะข้ามเหตุการณ์ onunload หากแท็บ / หน้าต่าง / โปรแกรมถูกปิด
Powerlord

5

เทียบเท่ากับคำตอบที่ยอมรับใน jQuery 1.11:

$(window).on("beforeunload", function () {
    return "Please don't leave me!";
});

ตัวอย่าง JSFiddle

คำตอบของ altCognito ใช้unloadเหตุการณ์ซึ่งเกิดขึ้นช้าเกินไปสำหรับ JavaScript ที่จะยกเลิกการนำทาง


3

ใช้onunload

สำหรับ jQuery ฉันคิดว่ามันใช้งานได้:

$(window).unload(function() { 
  alert("Unloading"); 
  return falseIfYouWantToButBeCareful();
});

การส่งคืนเท็จจะไม่ยกเลิกการยกเลิกการโหลดอย่างน่าเสียดาย - unloadเหตุการณ์เริ่มทำงานเมื่อผู้ใช้ออกจากหน้าเว็บbeforeunloadซึ่งแตกต่างจากที่เกิดขึ้นก่อนหน้านี้ (และอาจถูกยกเลิก)
Jimbo

@altCognito: คุณให้ความคิดที่ดีกับ falseIfYouWantToButBeCareful () ตอนนี้ฉันสามารถหลีกเลี่ยงป๊อปอัปเริ่มต้นที่ IE หรือ FF กำหนดได้ แต่สำหรับโครเมี่ยมมันไม่ทำงาน มองเข้าไป
user367134

3

ข้อความแสดงข้อผิดพลาดที่แนะนำนั้นอาจซ้ำกับข้อความแสดงข้อผิดพลาดที่เบราว์เซอร์แสดงอยู่แล้ว ใน Chrome ข้อความแสดงข้อผิดพลาดที่คล้ายกัน 2 ข้อความจะปรากฏขึ้นทีละข้อความในหน้าต่างเดียวกัน

ใน Chrome ข้อความที่แสดงหลังข้อความที่กำหนดเองคือ "คุณแน่ใจหรือไม่ว่าต้องการออกจากหน้านี้" ใน firefox จะไม่แสดงข้อความแสดงข้อผิดพลาดที่เรากำหนดเองเลย (แต่ยังคงแสดงกล่องโต้ตอบ)

ข้อความแสดงข้อผิดพลาดที่เหมาะสมกว่าอาจเป็น:

window.onbeforeunload = function() {
    return "If you leave this page, you will lose any unsaved changes.";
}

หรือสไตล์ stackoverflow: "คุณได้เริ่มเขียนหรือแก้ไขโพสต์แล้ว"


2

หากคุณจับปุ่มย้อนกลับ / ไปข้างหน้าของเบราว์เซอร์และไม่ต้องการออกไปคุณสามารถใช้:

window.addEventListener('popstate', function() {
    if (window.location.origin !== 'http://example.com') {
        // Do something if not your domain
    } else if (window.location.href === 'http://example.com/sign-in/step-1') {
        window.history.go(2); // Skip the already-signed-in pages if the forward button was clicked
    } else if (window.location.href === 'http://example.com/sign-in/step-2') {
        window.history.go(-2); // Skip the already-signed-in pages if the back button was clicked
    } else {
        // Let it do its thing
    }
});

มิฉะนั้นคุณสามารถใช้เหตุการณ์beforeunload ได้แต่ข้อความอาจทำงานข้ามเบราว์เซอร์หรือไม่ก็ได้และต้องส่งคืนสิ่งที่บังคับให้มีพรอมต์ในตัว

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