अवरोधन पृष्ठ निकास घटना


117

जब मेरे सिस्टम के भीतर एक पृष्ठ का संपादन होता है, तो एक उपयोगकर्ता किसी अन्य वेबसाइट पर नेविगेट करने का निर्णय ले सकता है और ऐसा करने में वे सभी संपादन खो सकते हैं जिन्हें उन्होंने सहेजा नहीं है।

मैं किसी अन्य पेज पर जाने के लिए किसी भी प्रयास को रोकना चाहता हूं और उपयोगकर्ता को यह सुनिश्चित करने के लिए प्रेरित करना चाहता हूं कि वे ऐसा चाहते हैं क्योंकि वे अपने वर्तमान काम को संभवतः खो सकते हैं।

जीमेल इसी तरह से करता है। उदाहरण के लिए, एक नया ईमेल लिखें, संदेश निकाय में लिखना शुरू करें और पता बार में एक नया स्थान दर्ज करें (जैसे twitter.com या कुछ और)। यह पूछने का संकेत देगा "क्या आप सुनिश्चित हैं?"

विचार यह कैसे दोहराने के लिए? मैं IE8 को लक्षित कर रहा हूं, लेकिन FF और Chrome के साथ भी संगत रहना चाहूंगा।


जवाबों:


154

घोमी के उत्तर के समान है, लेकिन यह IE और फ़ायरफ़ॉक्स के पुराने संस्करणों का भी समर्थन करता है।

window.onbeforeunload = function (e) {
  var message = "Your confirmation message goes here.",
  e = e || window.event;
  // For IE and Firefox
  if (e) {
    e.returnValue = message;
  }

  // For Safari
  return message;
};

1
क्या आप पहली पंक्ति (var message = ...) समझा सकते हैं? मुझे नहीं पता कि वह अल्पविराम और दूसरी अभिव्यक्ति क्या कर रहा है।
mtmurdock

7
@mtmurdock कई वेरिएबल्स को घोषित करने के लिए सिर्फ जावास्क्रिप्ट सिंटैक्स है। var foo, bar;के रूप में ही हैvar foo; var bar;
टी Nguyen

4
@mtmurdock, दूसरा कथन " var e = e || window.event?" मतलब ई के बराबर पैरामीटर (यदि यह सत्य है) या window.event अगर सत्य नहीं है। यदि पैरामीटर शून्य है , तो यह सत्य नहीं होगा ।
टी न्गुयेन

3
IE8 में @Blieque addEventListener समर्थित नहीं है। सवाल पढ़े बिना भी लोगों के उत्तरों को संपादित न करें।
एली ग्रे

2
Chrome में कोई भी अधिक काम नहीं करता (पदावनत): Developers.google.com/web/updates/2016/04/…
Mic Schwab

25

इस लेख को देखें। आप जिस सुविधा की तलाश कर रहे हैं, वह ऑनबॉर्फ़नलोड है

नमूना कोड:

  <script language="JavaScript">
  window.onbeforeunload = confirmExit;
  function confirmExit()
  {
    return "You have attempted to leave this page.  If you have made any changes to the fields without clicking the Save button, your changes will be lost.  Are you sure you want to exit this page?";
  }
</script>

2
क्या इस बात की पहचान करने का कोई तरीका है कि उपयोगकर्ता ने "इस पृष्ठ पर रहें" के बजाय "इस पृष्ठ को छोड़ दें" विकल्प चुना है?
शिल्पा सोनी

@ShilpaSoni आपको जल्द ही एक बाद का अनलोड ईवेंट, developer.mozilla.org/en-US/docs/Web/API/Window/unload_event मिल जाएगा, लेकिन मुझे नहीं लगता कि एक तुल्यकालिक तरीका है।
स्काइपिलॉट

6

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

window.onbeforeunload=function(e){
  // only take action (iterate) if my SCHEDULED_REQUEST object contains data        
  for (var key in SCHEDULED_REQUEST){   
    postRequest(SCHEDULED_REQUEST); // post and empty SCHEDULED_REQUEST object
    for (var i=0;i<1000;i++){
      // do something unnoticable but time consuming like writing a lot to console
      console.log('buying some time to finish saving data'); 
    };
    break;
  };
}; // no return string --> user will leave as normal but data is send to server

संपादित करें: यह भी देखें सिंक्रोनस_जैक्स और कैसे करें कि जेकरी के साथ


मुझे पॉपअप का यह विकल्प पसंद है। सुझाव के लिए धन्यवाद, रेमी।
क्रिस बैलेंस

2
यह बिल्कुल कोई मतलब नहीं है -1। जावास्क्रिप्ट को थ्रेडेड नहीं किया जाता है जो आप कर रहे हैं एक पोस्टरैपेस्ट कर रहा है और फिर बिना किसी को कुछ भी करने की अनुमति के बिना साइट की गणना रोक रहा है (अपने पोस्टरॉरेस्ट सहित, इस बीच पहले से ही कम्प्यूट पॉज़ से पहले भेजा गया था)।
fmsf

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

6
मैं उत्पादन में उपयोग नहीं होगा। कंसोल.लॉग क्रॉसब्रोसर नहीं है; प्रत्येक उत्तरवर्ती पिछले वाले की देरी से ग्रस्त है (जिसका अर्थ यह भी है कि पृष्ठ आपके लूप की अवधि के लिए वहीं लटका रहेगा। * अन्य घोषणा); अनुरोध समानांतर में शुरू नहीं हुए हैं; आपको वास्तव में अपने अनुरोध भेजने की गारंटी नहीं है। अगर मुझे इस समस्या का सामना करने के लिए मजबूर किया गया था, तो मैं केवल एक अनुरोध के साथ एक तुल्यकालिक एजैक्स अनुरोध के साथ जाऊंगा। कई अनुरोधों के साथ, मैं async ajax अनुरोधों और एक लूप का उपयोग करता हूं जो अनुरोधों के कॉलबैक से परिणाम (या तो सफलता या त्रुटि) की जांच करता है।
फ्रिज

मुझे नहीं पता था कि कंसोल.लॉग क्रॉस-ब्राउज़र नहीं है और एक सिंक्रोनस अजाक्स अनुरोध वास्तव में पसंदीदा समाधान (एकल अनुरोध के लिए) होना चाहिए। उल्लेख SCHEDULED_REQUESTएक ऐसी वस्तु है जो सर्वर पर भेजी जाने वाली किसी भी गैर-जरूरी जानकारी को एक्यूमुलेट करता है, जैसे डेटा का एक बफर, प्रभावी रूप से एक से कई अनुरोधों को जोड़ना (बेशक इन अनुरोधों का यूआरएल एक ही है)। अनलोड के पहले एक सिंक्रोनस अजाक्स अनुरोध का उपयोग करके समस्या क्रॉस-ब्राउज़र को हल करना चाहिए जैसा आपने कहा था। आपकी बहुमूल्य टिप्पणी के लिए धन्यवाद!
रेमी

0

मेरे पास ऐसे उपयोगकर्ता हैं जो सभी आवश्यक डेटा को पूरा नहीं कर रहे हैं।

<cfset unloadCheck=0>//a ColdFusion precheck in my page generation to see if unload check is needed
var erMsg="";
$(document).ready(function(){
<cfif q.myData eq "">
    <cfset unloadCheck=1>
    $("#myInput").change(function(){
        verify(); //function elsewhere that checks all fields and populates erMsg with error messages for any fail(s)
        if(erMsg=="") window.onbeforeunload = null; //all OK so let them pass
        else window.onbeforeunload = confirmExit(); //borrowed from Jantimon above;
    });
});
<cfif unloadCheck><!--- if any are outstanding, set the error message and the unload alert --->
    verify();
    window.onbeforeunload = confirmExit;
    function confirmExit() {return "Data is incomplete for this Case:"+erMsg;}
</cfif>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.