วิธีแสดง“ คุณแน่ใจหรือไม่ว่าต้องการออกจากหน้านี้” เมื่อมีการเปลี่ยนแปลงเกิดขึ้น?


267

ใน stackoverflow ที่นี่หากคุณเริ่มทำการเปลี่ยนแปลงแล้วคุณพยายามที่จะออกไปจากหน้านั้นปุ่มยืนยันจาวาสคริปต์จะปรากฏขึ้นและถามว่า: "คุณแน่ใจหรือไม่ว่าคุณต้องการออกไปจากหน้านี้" บลู blah bloo ...

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

ฉันลองสิ่งต่อไปนี้ แต่ก็ยังใช้งานไม่ได้:

<html>
<body>
    <p>Close the page to trigger the onunload event.</p>
    <script type="text/javascript">
        var changes = false;        
        window.onbeforeunload = function() {
            if (changes)
            {
                var message = "Are you sure you want to navigate away from this page?\n\nYou have started writing or editing a post.\n\nPress OK to continue or Cancel to stay on the current page.";
                if (confirm(message)) return true;
                else return false;
            }
        }
    </script>

    <input type='text' onchange='changes=true;'> </input>
</body>
</html>

ทุกคนสามารถโพสต์ตัวอย่างได้หรือไม่


3
ในการทำให้ตัวอย่างของคุณทำงานเปลี่ยนฟังก์ชันเป็น: myFunction () {window.onbeforeunload = "message"; } จากนั้นเปลี่ยนอินพุต: <input type = 'text' onchange = 'myFunction ();'> </input>
Keith

ที่เกี่ยวข้อง: stackoverflow.com/q/821011/435605
AlikElzin-kilaka

คำตอบ:


367

อัปเดต (2017)

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

// Enable navigation prompt
window.onbeforeunload = function() {
    return true;
};
// Remove navigation prompt
window.onbeforeunload = null;

อ่านด้านล่างเพื่อรับการสนับสนุนเบราว์เซอร์รุ่นเก่า

อัปเดต (2013)

คำตอบเดิมนั้นเหมาะสำหรับ IE6-8 และ FX1-3.5 (ซึ่งเป็นสิ่งที่เรากำหนดเป้าหมายไว้ในปี 2552 เมื่อมีการเขียน) แต่ค่อนข้างล้าสมัยในขณะนี้และจะไม่ทำงานในเบราว์เซอร์ปัจจุบันส่วนใหญ่ - ฉันออกไปแล้ว มันด้านล่างสำหรับการอ้างอิง

window.onbeforeunloadไม่ได้รับการรักษาอย่างต่อเนื่องโดยเบราว์เซอร์ ควรเป็นการอ้างอิงฟังก์ชันและไม่ใช่สตริง (ตามคำตอบดั้งเดิมที่ระบุไว้) แต่จะทำงานในเบราว์เซอร์รุ่นเก่าเนื่องจากการตรวจสอบส่วนใหญ่ดูเหมือนจะเป็นสิ่งที่กำหนดให้หรือไม่onbeforeunload(รวมถึงฟังก์ชันที่ส่งคืนnull)

คุณตั้งค่าwindow.onbeforeunloadการอ้างอิงฟังก์ชัน แต่ในเบราว์เซอร์รุ่นเก่าคุณต้องตั้งค่าreturnValueเหตุการณ์แทนการส่งคืนสตริง:

var confirmOnPageExit = function (e) 
{
    // If we haven't been passed the event get the window.event
    e = e || window.event;

    var message = 'Any text will block the navigation and display a prompt';

    // For IE6-8 and Firefox prior to version 4
    if (e) 
    {
        e.returnValue = message;
    }

    // For Chrome, Safari, IE8+ and Opera 12+
    return message;
};

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

// Turn it on - assign the function that returns the string
window.onbeforeunload = confirmOnPageExit;

// Turn it off - remove the function entirely
window.onbeforeunload = null;

คำตอบเดิม (ทำงานในปี 2009)

วิธีเปิดใช้งาน:

window.onbeforeunload = "Are you sure you want to leave?";

วิธีปิดใช้งาน:

window.onbeforeunload = null;

โปรดจำไว้ว่านี่ไม่ใช่เหตุการณ์ปกติ - คุณไม่สามารถผูกมันด้วยวิธีมาตรฐาน

เพื่อตรวจสอบค่า? ขึ้นอยู่กับกรอบการตรวจสอบของคุณ

ใน jQuery นี่อาจเป็นสิ่งที่ชอบ (ตัวอย่างพื้นฐานมาก):

$('input').change(function() {
    if( $(this).val() != "" )
        window.onbeforeunload = "Are you sure you want to leave?";
});

4
นั่นจะเป็นสิ่งที่ต้องการ: $ ('input: text'). change (function () {window.onbeforeunload = $ ('input: text [value! = ""]'). ความยาว> 0? "คำเตือน": null ;});
Keith

1
สำหรับการตรวจสอบง่ายหรือคุณสามารถเพิ่มการตรวจสอบที่ซับซ้อนมากขึ้นในแต่ละการเปลี่ยนแปลง
คี ธ

1
เป็นที่น่าสังเกตว่าวิธีการ 'returnValue' เป็นวิธีการเดียวที่ระบุไว้ในมาตรฐานดังนั้นจึงไม่ใช่แค่สำหรับ IE6-8 แต่สำหรับเบราว์เซอร์ที่ได้มาตรฐานตามมาตรฐานทั้งหมด (ในกรณีนี้ไม่รวมถึง Chrome, Safari และ Opera)
rmcclellan

3
$("#submit_button").click(function() { window.onbeforeunload = null; });ในการหยุดการแจ้งเตือนในการส่งแบบฟอร์มที่ผมใช้ ตอนแรกฉันใช้ปุ่มเหตุการณ์ onclick แต่ก็ไม่ได้ใช้งานได้ดี แต่ก็ใช้งานไม่ได้กับ IE8
Andy Beverley

1
@ AlikElzin-kilaka คุณทำไม่ได้ หากคุณต้องการเปลี่ยนข้อความป๊อปอัพคุณต้องสร้างป๊อปอัปที่กำหนดเองของคุณเอง แต่นั่นไม่สามารถปิดกั้นwindow.onbeforeunloadเหตุการณ์
Keith

38

onbeforeunloadMicrosoft ลัทธิเป็นสิ่งที่ใกล้เราจะต้องแก้ปัญหาที่มาตรฐาน แต่จะตระหนักว่าการสนับสนุนเบราว์เซอร์ที่ไม่สม่ำเสมอ; เช่น Opera ใช้งานได้เฉพาะในเวอร์ชั่น 12 และใหม่กว่าเท่านั้น (ยังอยู่ในช่วงเบต้าของการเขียนนี้)

นอกจากนี้สำหรับเข้ากันได้สูงสุดที่คุณจะต้องทำมากกว่าเพียงแค่กลับสตริงตามที่อธิบายไว้ในMozilla พัฒนาเครือข่าย

ตัวอย่าง:กำหนดสองฟังก์ชั่นต่อไปนี้สำหรับการเปิด / ปิดการใช้งานพรอมต์การนำทาง (เช่นตัวอย่าง MDN):

function enableBeforeUnload() {
    window.onbeforeunload = function (e) {
        return "Discard changes?";
    };
}
function disableBeforeUnload() {
    window.onbeforeunload = null;
}

จากนั้นกำหนดรูปแบบดังนี้:

<form method="POST" action="" onsubmit="disableBeforeUnload();">
    <textarea name="text"
              onchange="enableBeforeUnload();"
              onkeyup="enableBeforeUnload();">
    </textarea>
    <button type="submit">Save</button>
</form>

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


1
ตามเว็บไซต์ของ Mozill เบราว์เซอร์เดสก์ท็อปล่าสุดสนับสนุน: developer.mozilla.org/en/DOM/window.onbeforeunload
Hengjie

Microsoft-ism เป็นคำที่ยอดเยี่ยม
ลุคเทย์เลอร์


18

ด้วย JQueryสิ่งนี้ค่อนข้างง่ายที่จะทำ เนื่องจากคุณสามารถผูกกับชุด

ยังไม่เพียงพอที่จะทำการโหลดก่อนหน้านี้คุณต้องการทริกเกอร์การนำทางเฉพาะเมื่อมีคนเริ่มแก้ไขสิ่งต่างๆ


2
ดูเหมือนจะไม่สามารถเข้าถึงโพสต์บล็อกของ @jonstjohn บางทีเขาอาจจะเป็นเพื่อนและชี้แนะทิศทางที่ถูกต้องให้เรา? : D
FLGMwt

14
=> 500 ข้อผิดพลาดภายใน นั่นเป็นเหตุผลว่าทำไมลิงก์เลิกใช้แล้วใน SO ลงคะแนนจนกว่าจะได้รับการแก้ไข
Lo 19c

หน้าเว็บนี้ไม่สามารถใช้งานได้
Mateusz

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

2
ลิงค์ต้นฉบับจากจอนเซนต์จอห์นเสียดังนั้นฉันปรับปรุงให้Wayback เครื่องรุ่นของมัน เนื้อหาของลิงค์สามารถพบได้ในเว็บไซต์อื่น ๆ แต่ฉันคิดว่าเป็นการดีกว่าที่จะ "รักษา" สิ่งที่แซมเพิ่มไว้
Alvaro Montoro

14

jquerys 'beforeunload' ทำงานได้ดีสำหรับฉัน

$(window).bind('beforeunload', function(){
    if( $('input').val() !== '' ){
        return "It looks like you have input you haven't submitted."
    }
});

การผูกได้เลิกใช้แล้วและมีโค้ดรุ่นใหม่ที่คล้ายกับคำตอบนี้: stackoverflow.com/a/1889450/908677
Elijah Lofgren


11

นี่เป็นวิธีที่ง่ายในการนำเสนอข้อความหากมีการป้อนข้อมูลลงในแบบฟอร์มและไม่แสดงข้อความหากมีการส่งแบบฟอร์ม:

$(function () {
    $("input, textarea, select").on("input change", function() {
        window.onbeforeunload = window.onbeforeunload || function (e) {
            return "You have unsaved changes.  Do you want to leave this page and lose your changes?";
        };
    });
    $("form").on("submit", function() {
        window.onbeforeunload = null;
    });
})

8

หากต้องการขยายคำตอบที่น่าทึ่งของ Keith :

ข้อความเตือนที่กำหนดเอง

หากต้องการอนุญาตข้อความเตือนที่กำหนดเองคุณสามารถรวมข้อความไว้ในฟังก์ชันดังนี้:

function preventNavigation(message) {
    var confirmOnPageExit = function (e) {
        // If we haven't been passed the event get the window.event
        e = e || window.event;

        // For IE6-8 and Firefox prior to version 4
        if (e)
        {
            e.returnValue = message;
        }

        // For Chrome, Safari, IE8+ and Opera 12+
        return message;
    };
    window.onbeforeunload = confirmOnPageExit;
}

จากนั้นเพียงเรียกใช้ฟังก์ชันนั้นพร้อมกับข้อความที่กำหนดเองของคุณ:

preventNavigation("Baby, please don't go!!!");

เปิดใช้งานการนำทางอีกครั้ง

การเปิดใช้งานระบบนำทางทั้งหมดที่คุณต้องทำคือการตั้งค่าไปwindow.onbeforeunload nullนี่คือฟังก์ชั่นเล็ก ๆ ที่เรียบร้อยที่สามารถเรียกได้ทุกที่:

function enableNavigation() {
    window.onbeforeunload = null;
}

การใช้ jQuery เพื่อโยงสิ่งนี้เข้ากับองค์ประกอบ

หากใช้ jQuery สิ่งนี้สามารถผูกกับองค์ประกอบทั้งหมดของแบบฟอร์มดังนี้:

$("#yourForm :input").change(function() {
    preventNavigation("You have not saved the form. Any \
        changes will be lost if you leave this page.");
});

จากนั้นให้อนุญาตให้ส่งแบบฟอร์ม:

$("#yourForm").on("submit", function(event) {
    enableNavigation();
});

แบบฟอร์มที่แก้ไขแบบไดนามิก:

preventNavigation()และenableNavigation()สามารถผูกกับฟังก์ชั่นอื่น ๆ ตามต้องการเช่นการปรับเปลี่ยนแบบไดนามิกหรือคลิกที่ปุ่มที่ส่งคำขอ AJAX ฉันทำสิ่งนี้โดยการเพิ่มองค์ประกอบอินพุตที่ซ่อนอยู่ในแบบฟอร์ม:

<input id="dummy_input" type="hidden" />

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

function somethingThatModifiesAFormDynamically() {

    // Do something that modifies a form

    // ...
    $("#dummy_input").trigger("change");
    // ...
}

3

ลองที่นี่ลองใช้งานได้ 100%

<html>
<body>
<script>
var warning = true;
window.onbeforeunload = function() {  
  if (warning) {  
    return "You have made changes on this page that you have not yet confirmed. If you navigate away from this page you will lose your unsaved changes";  
    }  
}

$('form').submit(function() {
   window.onbeforeunload = null;
});
</script>
</body>
</html>

3

มาตรฐานรัฐที่กระตุ้นให้สามารถควบคุมได้โดยการยกเลิกbeforeunloadเหตุการณ์หรือการตั้งค่าที่ส่งกลับไปยังค่าที่ไม่ใช่ null นอกจากนี้ยังระบุว่าผู้เขียนควรใช้ Event.preventDefault () แทน returnValue และข้อความที่แสดงให้ผู้ใช้ไม่สามารถปรับแต่งได้

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

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

window.addEventListener('beforeunload', function (e) {
    // Cancel the event as stated by the standard.
    e.preventDefault();
    // Chrome requires returnValue to be set.
    e.returnValue = '';
});
    
window.location = 'about:blank';


2

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

หากคุณกำลังใช้ ajax เพื่อคอมมิทการเปลี่ยนแปลงคุณสามารถตั้งค่าแฟล็กเป็นfalseหลังจากมีการคอมมิท (เช่นในเหตุการณ์ความสำเร็จ ajax)


1

คุณสามารถเพิ่มonchangeเหตุการณ์บน textarea (หรือฟิลด์อื่น ๆ ) ที่ตั้งค่าตัวแปรใน JS เมื่อผู้ใช้พยายามที่จะปิดหน้า (window.onunload) คุณตรวจสอบค่าของตัวแปรนั้นและแสดงการแจ้งเตือนตาม


1
คุณไม่สามารถทำสิ่งนี้ - alertและconfirmถูกบล็อกระหว่างwindow.onbeforeunloadและwindow.onunload(อย่างน้อยที่สุดในเวอร์ชัน Chrome บนพีซีของฉัน แต่อาจมีในทุกเบราว์เซอร์ที่เคยรองรับตัวจัดการเหล่านั้น)
Mark Amery

1

จากคำตอบทั้งหมดในกระทู้นี้ฉันเขียนโค้ดต่อไปนี้และมันใช้ได้กับฉัน

หากคุณมีแท็กอินพุต / textarea เพียงบางรายการเท่านั้นที่ต้องมีการตรวจสอบเหตุการณ์ onunload คุณสามารถกำหนดแอตทริบิวต์ข้อมูล HTML5 เป็น data-onunload="true"

สำหรับเช่น

<input type="text" data-onunload="true" />
<textarea data-onunload="true"></textarea>

และ Javascript (jQuery) สามารถมีลักษณะเช่นนี้:

$(document).ready(function(){
    window.onbeforeunload = function(e) {
        var returnFlag = false;
        $('textarea, input').each(function(){
            if($(this).attr('data-onunload') == 'true' && $(this).val() != '')
                returnFlag = true;
        });

        if(returnFlag)
            return "Sure you want to leave?";   
    };
});

2
ดูเพิ่มเติม"ด้วยเหตุผลบางประการเบราว์เซอร์ Webkit-based ไม่เป็นไปตามสเปคสำหรับกล่องโต้ตอบ"ใน MDN ของเอกสาร beforeunload
Arjan

1

นี่คือ html ของฉัน

<!DOCTYPE HMTL>
<meta charset="UTF-8">
<html>
<head>
<title>Home</title>
<script type="text/javascript" src="script.js"></script>
</head>

 <body onload="myFunction()">
    <h1 id="belong">
        Welcome To My Home
    </h1>
    <p>
        <a id="replaceME" onclick="myFunction2(event)" href="https://www.ccis.edu">I am a student at Columbia College of Missouri.</a>
    </p>
</body>

และนี่คือวิธีที่ฉันทำสิ่งที่คล้ายกันใน javaScript

var myGlobalNameHolder ="";

function myFunction(){
var myString = prompt("Enter a name", "Name Goes Here");
    myGlobalNameHolder = myString;
    if (myString != null) {
        document.getElementById("replaceME").innerHTML =
        "Hello " + myString + ". Welcome to my site";

        document.getElementById("belong").innerHTML =
        "A place you belong";
    }   
}

// create a function to pass our event too
function myFunction2(event) {   
// variable to make our event short and sweet
var x=window.onbeforeunload;
// logic to make the confirm and alert boxes
if (confirm("Are you sure you want to leave my page?") == true) {
    x = alert("Thank you " + myGlobalNameHolder + " for visiting!");
}
}

0

ก็สามารถทำได้อย่างง่ายดายโดยการตั้งค่าChangeFlagจริงในonChangeกรณีที่TextArea ใช้จาวาสคริปต์เพื่อแสดงกล่องโต้ตอบยืนยันตามค่าChangeFlag ละทิ้งแบบฟอร์มและไปที่หน้าที่ร้องขอหากยืนยันส่งคืนจริงไม่ทำอะไรเลย



-1

มีพารามิเตอร์ "onunload" สำหรับแท็ก body ที่คุณสามารถเรียกใช้ฟังก์ชันจาวาสคริปต์ได้ ถ้ามันกลับเท็จมันจะป้องกันการนำทางไป


13
โชคดีที่มันใช้งานไม่ได้จริง <body onunload="return false;">มิฉะนั้นฉันเกลียดที่จะเยี่ยมชมหน้าเว็บที่มี
SørenLøvborg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.