मैं OnBeforeUnload डायलॉग को कैसे ओवरराइड कर सकता हूं और इसे अपने से बदल सकता हूं?


346

मुझे पेज (एक बहुत ही सामान्य समस्या) छोड़ने से पहले उपयोगकर्ताओं को सहेजे न गए परिवर्तनों के बारे में चेतावनी देने की आवश्यकता है।

window.onbeforeunload=handler

यह काम करता है लेकिन यह एक अनियमित मानक संदेश के साथ एक डिफ़ॉल्ट संवाद बढ़ाता है जो मेरे स्वयं के पाठ को लपेटता है। मुझे या तो मानक संदेश को पूरी तरह से बदलने की आवश्यकता है, इसलिए मेरा पाठ स्पष्ट है, या (और भी बेहतर) पूरे डायल को एक न्यूडल का उपयोग करके एक मोडल संवाद के साथ बदलें।

अब तक मैं असफल रहा हूँ और मुझे कोई और नहीं मिला है जिसका उत्तर लगता है। क्या यह भी संभव है?

मेरे पृष्ठ में जावास्क्रिप्ट:

<script type="text/javascript">   
   window.onbeforeunload=closeIt;
</script>

बंद करें () फ़ंक्शन:

function closeIt()
{
  if (changes == "true" || files == "true")
  {
      return "Here you can append a custom message to the default dialog.";
  }
}

JQuery और jqModal का उपयोग करके मैंने इस तरह की कोशिश की है (कस्टम पुष्टि संवाद का उपयोग करके):

$(window).beforeunload(function() {
        confirm('new message: ' + this.href + ' !', this.href);
        return false;
    });

जो भी काम नहीं करता है - मैं पहले की घटना के लिए बाध्य नहीं लग सकता।


1
क्या आप अपने वर्तमान कोड का उदाहरण दे सकते हैं और यह क्या पैदा करता है?
ओवेन

ओवेन सही है। और, इसके पीछे का कारण सुरक्षा है। किसी पेज को अनलोडिंग से रोकना वेब रूपों और इस तरह से उपयोगी है, लेकिन उपयोगकर्ता को पेज पर रहने के लिए मूर्ख बनाने के लिए एक दुर्भावनापूर्ण साइट द्वारा इसका आसानी से फायदा उठाया जा सकता है। यही कारण है कि वेब ब्राउज़र मानक संदेश को लागू करते हैं और कस्टम पाठ सम्मिलित करने के लिए यह तंत्र है।
प्लिस्कोगलन

अधिक जानकारी के लिए यहां देखें: stackoverflow.com/questions/140460
बेन मैकइंटायर


1
क्रोम में संभव नहीं, संदर्भ: stackoverflow.com/questions/37782104/…
अभिजीत

जवाबों:


300

आप के लिए डिफ़ॉल्ट संवाद को संशोधित नहीं कर सकते onbeforeunload, इसलिए आपका सबसे अच्छा दांव इसके साथ काम करना हो सकता है।

window.onbeforeunload = function() {
    return 'You have unsaved changes!';
}

Microsoft से इसका संदर्भ यहां दिया गया है :

जब एक स्ट्रिंग window.event की रिटर्न वेल्यू प्रॉपर्टी को दी जाती है, तो एक डायलॉग बॉक्स दिखाई देता है, जो यूजर्स को मौजूदा पेज पर बने रहने और उसे सौंपे गए स्ट्रिंग को बनाए रखने का विकल्प देता है। डिफ़ॉल्ट विवरण जो संवाद बॉक्स में दिखाई देता है, "क्या आप सुनिश्चित हैं कि आप इस पृष्ठ से दूर जाना चाहते हैं? ... वर्तमान पृष्ठ पर बने रहने के लिए जारी रखने के लिए ठीक दबाएं या रद्द करें", हटाया या परिवर्तित नहीं किया जा सकता है।

समस्या यह प्रतीत होती है:

  1. जब onbeforeunloadकहा जाता है, तो यह हैंडलर के रिटर्न मान के रूप में ले जाएगा window.event.returnValue
  2. यह एक स्ट्रिंग के रूप में रिटर्न मान को पार्स करेगा (जब तक कि यह शून्य न हो)।
  3. चूंकि falseएक तार के रूप में पार्स किया जाता है, संवाद बॉक्स में आग लग जाएगी, जो तब एक उपयुक्त true/ पास होगी false

इसका परिणाम यह है कि, इसे डिफ़ॉल्ट संवाद से रोकने के लिए असाइन falseकरने का एक तरीका प्रतीत नहीं होता है onbeforeunload

JQuery पर अतिरिक्त नोट:

  • JQuery में ईवेंट सेट करना समस्याग्रस्त हो सकता है, क्योंकि इससे अन्य onbeforeunloadईवेंट भी हो सकते हैं। यदि आप केवल अपने अनलोड घटना के लिए चाहते हैं तो मैं इसके लिए सादे ol 'जावास्क्रिप्ट से चिपके रहूँगा।
  • jQuery के लिए कोई शॉर्टकट नहीं है onbeforeunloadइसलिए आपको जेनेरिक bindसिंटैक्स का उपयोग करना होगा ।

    $(window).bind('beforeunload', function() {} );

09/04/2018 को संपादित करें : onbeforeunload संवादों में कस्टम संदेश क्रोम -51 के बाद से हटाए गए हैं (cf: release )


20
मैंने पाया है कि अंत में दिए गए JQuery के उदाहरण फ़ायरफ़ॉक्स में काम नहीं करते हैं। इसके बजाय सरल तरीके से छड़ी करें: window.onbeforeunload = function () {...}
jb।

21
बस एक नोट है कि फ़ायरफ़ॉक्स को हाल ही में बदल दिया गया था ताकि संवाद में पाठ को भी अनुकूलित न किया जा सके: Bugzilla.mozilla.org/show_bug.cgi?id=588292
डेविड हैमंड

15
लेकिन फिर फेसबुक एक कस्टम डायलॉग बॉक्स कैसे प्रदान करता है? उदाहरण के लिए, संदेश पृष्ठ पर जाएं, अपने मित्र के संदेश का उत्तर दें और फिर भेजने से पहले दूसरे लिंक पर क्लिक करके देखें। आपको एक कस्टम डायलॉग पॉपअप दिखाई देगा
वरुण

20
@ वरुण - पुरानी खबर है लेकिन फेसबुक संभवतः अपने सभी एंकरों की क्लिक ईवेंट पर हैंडलर लगा रहे हैं, लेकिन यदि आप ब्राउज़र में यूआरएल को फिर से लिखते हैं या विंडो को बंद करते हैं, तो यह मानक पद्धति का पुन: उल्लेख करता है, जिस पर उनका कोई नियंत्रण नहीं है।
तबलू क्विजिको

1
@ वरुण मुझे इस बात का भी आश्चर्य है कि यह ऐसा तरीका जो असंभव है, इसका उत्तर के रूप में चिह्नित किया गया है और इसमें 150 अपवर्जन हैं ... बस एहसास हुआ, एफबी का कस्टम संदेश केवल उनकी साइट के अंदर लिंक के माध्यम से उपलब्ध है। यदि आप बस दूर नेविगेट नहीं ...
सेबेस्टियन रिच

28

मेरे लिए क्या काम किया है, jQuery का उपयोग करके और IE8, क्रोम और फ़ायरफ़ॉक्स में परीक्षण किया गया है:

$(window).bind("beforeunload",function(event) {
    if(hasChanged) return "You have unsaved changes";
});

यदि कोई संकेत की आवश्यकता नहीं है तो कुछ भी वापस नहीं करना महत्वपूर्ण है क्योंकि यहां IE और अन्य ब्राउज़र व्यवहारों के बीच अंतर हैं।


दिलचस्प है, event.returnValueIE में एकमात्र "अनुमोदित" पद्धति है। IE यह कहने के लिए आगे बढ़ता है कि "इस संपत्ति का मूल्य फ़ंक्शन द्वारा लौटाए गए मानों पर वरीयता लेता है, जैसे कि Microsoft JScript स्टेटमेंट के माध्यम से।" .. return(घटना से) और के बीच एक गारंटीकृत सहसंबंध देखकर अच्छा event.returnValue

21

हालांकि कुछ परिस्थितियों में आप बॉक्स के बारे में कुछ नहीं कर सकते हैं, आप किसी लिंक पर क्लिक करने वाले को रोक सकते हैं। मेरे लिए, यह अधिकांश परिदृश्यों के लिए प्रयास के लायक था और एक गिरावट के रूप में, मैंने अनलोड घटना को छोड़ दिया है।

मैंने मानक jQuery डायलॉग के बजाय बॉक्सी का उपयोग किया है, यह यहां उपलब्ध है: http://onehackoranother.com/projects/jquery/boxy/

$(':input').change(function() {
    if(!is_dirty){
        // When the user changes a field on this page, set our is_dirty flag.
        is_dirty = true;
    }
});

$('a').mousedown(function(e) {
    if(is_dirty) {
        // if the user navigates away from this page via an anchor link, 
        //    popup a new boxy confirmation.
        answer = Boxy.confirm("You have made some changes which you might want to save.");
    }
});

window.onbeforeunload = function() {
if((is_dirty)&&(!answer)){
            // call this if the box wasn't shown.
    return 'You have made some changes which you might want to save.';
    }
};

आप किसी अन्य ईवेंट में संलग्न हो सकते हैं, और किस प्रकार के एंकर को क्लिक किया गया था, इस पर और अधिक फ़िल्टर कर सकते हैं, लेकिन यह मेरे लिए काम करता है और मैं जो करना चाहता हूं और दूसरों के उपयोग या सुधार के लिए एक उदाहरण के रूप में कार्य करता हूं। सोचा था कि मैं यह समाधान चाहने वालों के लिए साझा करूंगा।

मैंने कोड काट दिया है, इसलिए यह काम नहीं कर सकता है।


वापसी 'आपने कुछ बदलाव किए हैं जिन्हें आप बचाना चाहते हैं।' मेरे लिए काम नहीं किया। मुझे संदेश को 'चेतावनी_message' चर में संग्रहीत करना था और मैंने चेतावनी_message लौटा दी। तब केवल इसने मेरे लिए काम किया!
सुगन्या

क्या आपने IE, क्रोम, फ़ायरफ़ॉक्स में परीक्षण किया था?
किकेनेट

9

1) onbeforeunload का उपयोग करें, न कि onunload का।

2) महत्वपूर्ण बात यह है कि रिटर्न स्टेटमेंट को निष्पादित करने से बचें। मेरा मतलब यह नहीं है, इस से, अपने हैंडलर से लौटने से बचने के लिए। आप सभी सही लौटाते हैं, लेकिन आप यह सुनिश्चित करके करते हैं कि आप फ़ंक्शन के अंत तक पहुँचते हैं और रिटर्न स्टेटमेंट निष्पादित नहीं करते हैं। इन शर्तों के तहत अंतर्निहित मानक संवाद नहीं होता है।

3) आप कर सकते हैं, यदि आप onbeforeunload का उपयोग करते हैं, तो सर्वर पर सुव्यवस्थित करने के लिए अपने unbeforeunload हैंडलर में ajax कॉल चलाएं, लेकिन यह एक तुल्यकालिक होना चाहिए, और आपको अपने onbeforeunload हैंडलर में उत्तर की प्रतीक्षा करनी होगी और उसे संभालना होगा (अभी भी सम्मान हालत (2) ऊपर)। मैं यह करता हूं और यह ठीक काम करता है। यदि आप एक तुल्यकालिक अजाक्स कॉल करते हैं, तो प्रतिक्रिया वापस आने तक सब कुछ व्यवस्थित रहता है। यदि आप एक एसिंक्रोनस करते हैं, तो यह सोचकर कि आप सर्वर से उत्तर के बारे में परवाह नहीं करते हैं, पेज अनलोड होता रहता है और इस प्रक्रिया से आपका अजाक्स कॉल निरस्त हो जाता है - यदि यह चल रहा है तो रिमोट स्क्रिप्ट सहित।


सिर्फ FYI करें इसे पढ़ने वाला कोई भी व्यक्ति ^ Chrome में सिंक्रोनस AJAX कॉल को हटा रहा है
morganwebdev

4

return;संदेश के बजाय रखने का प्रयास करें .. यह मेरे लिए अधिकांश ब्राउज़र काम कर रहा है। (यह केवल संवाद के प्रस्तुतिकरण को रोकता है)

window.onbeforeunload = function(evt) {            
        //Your Extra Code
        return;
}

3
वापसी नल संवाद को खोलने से रोक देगा
ब्रेट वेबर

1
वापसी नल संवाद को खोलने से नहीं रोकेगा। मैंने इसे क्रोम में आज़माया है और ऐसा नहीं है।
रे

2
मैं IE में रे की टिप्पणी की पुष्टि कर सकता हूं। रिटर्निंग null"नल" के पाठ के साथ एक संवाद खोलेगा। हालांकि, return void(0);संवाद नहीं खोलेगा।
मकलस्टॉक

1
पहले से लोड फ़ंक्शन के अंदर कोई रिटर्न स्टेटमेंट नहीं डालने से, डायलॉग नहीं खुलेगा।
औउजीइआई


3

आप उपयोगकर्ता द्वारा दबाए गए कौन से बटन (ठीक या रद्द) का पता लगा सकते हैं, क्योंकि उपयोगकर्ता द्वारा पृष्ठ छोड़ते समय ऑनऑनलोड फ़ंक्शन तभी कहा जाता है। इस फफूंद में अल्थौग की संभावनाएं सीमित हैं, क्योंकि डोम का पतन हो रहा है। आप जावास्क्रिप्ट चला सकते हैं, लेकिन अजाक्स POST कुछ भी नहीं करता है इसलिए आप इस लॉगऑउट का उपयोग स्वचालित लॉगआउट के लिए नहीं कर सकते हैं। लेकिन उसके लिए एक उपाय है। Onunload funcion में window.open ('logout.php') निष्पादित किया जाता है, इसलिए उपयोगकर्ता एक नई विंडो खोलने के साथ लॉग आउट होगा।

function onunload = (){
    window.open('logout.php');
}

जब उपयोगकर्ता पृष्ठ छोड़ देता है या सक्रिय विंडो बंद कर देता है और उपयोगकर्ता 'logout.php' द्वारा लॉग आउट हो जाता है, तो यह कोड कहा जाता है। लॉगआउट php कोड शामिल होने पर तुरंत नई विंडो बंद हो जाती है:

window.close();

आप पहले से लोड और अनलोड कार्यों में एक तुल्यकालिक पोस्ट का उपयोग कर सकते हैं। खासकर यदि आपको सर्वर से डेटा वापस चाहिए। उन ब्लॉकों के भीतर कोई भी async कोड उस समय तक पूरा नहीं हो सकता जब तक पेज अनलोड नहीं हो जाता।
जेमिलोइ

3

मैंने उसी समस्या का सामना किया, मैं अपने संदेश के साथ अपना स्वयं का संवाद बॉक्स प्राप्त करना ठीक था, लेकिन मैंने जो समस्या का सामना किया था वह था: 1) यह सभी नेविगेटों पर संदेश दे रहा था जो मैं केवल क्लोज क्लिक के लिए चाहता हूं। 2) अपने स्वयं के पुष्टिकरण संदेश के साथ यदि उपयोगकर्ता इसे रद्द करता है तो भी यह ब्राउज़र के डिफ़ॉल्ट संवाद बॉक्स को दिखाता है।

निम्नलिखित समाधान कोड मुझे मिला, जिसे मैंने अपने मास्टर पृष्ठ पर लिखा था।

function closeMe(evt) {
    if (typeof evt == 'undefined') {
        evt = window.event; }
    if (evt && evt.clientX >= (window.event.screenX - 150) &&
        evt.clientY >= -150 && evt.clientY <= 0) {
        return "Do you want to log out of your current session?";
    }
}
window.onbeforeunload = closeMe;


1

"बाइंड" कमांड "एक" के विशेष संस्करण का उपयोग करने के बारे में क्या। एक बार जब ईवेंट हैंडलर पहली बार निष्पादित होता है, तो यह ईवेंट हैंडलर के रूप में स्वचालित रूप से हटा दिया जाता है।

$(window).one("beforeunload", BeforeUnload);

बहुत यकीन है कि यह .on ("पहले से लोड"
सेर्गी मिंड्रास

2
@SergiuMindras नहीं, यह है .one()- जो कि एक घटना श्रोता को केवल एक बार होने वाली घटना को सुनने के लिए संलग्न करता है: "तत्वों के लिए एक घटना के लिए एक हैंडलर संलग्न करें। हैंडलर को प्रति घटना के प्रकार के अनुसार एक बार प्रति तत्व पर निष्पादित किया जाता है।" api.jquery.com/one
सीन केंडल

0

कोणीय 9 दृष्टिकोण:

constructor() {
    window.addEventListener('beforeunload', (event: BeforeUnloadEvent) => {
     if (this.generatedBarcodeIndex) {
      event.preventDefault(); // for Firefox
      event.returnValue = ''; // for Chrome
      return '';
     }
     return false;
    });
   }

ब्राउज़र समर्थन और कस्टम संदेश को हटाने:

  • कस्टम ने 51 मिनट में कस्टम संदेश के लिए समर्थन हटा दिया
  • ओपेरा ने कस्टम संदेश के लिए समर्थन को 38 मिनट में हटा दिया
  • फ़ायरफ़ॉक्स ने 44.0 मिनट में कस्टम संदेश के लिए समर्थन हटा दिया
  • सफारी ने कस्टम संदेश के लिए समर्थन को 9.1 मिनट में हटा दिया
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.