সংরক্ষিত পরিবর্তনগুলি সহ ওয়েব পৃষ্ঠা ছেড়ে যাওয়ার আগে ব্যবহারকারীকে সতর্ক করুন


341

আমার আবেদনে ফর্মগুলির সাথে আমার কয়েকটি পৃষ্ঠা রয়েছে।

আমি কীভাবে ফর্মটি এমনভাবে সুরক্ষিত করতে পারি যে যদি কেউ ব্রাউজারের ট্যাব সরিয়ে নিয়ে যায় বা বন্ধ করে দেয় তবে সেগুলি নিশ্চিত করে জিজ্ঞাসা করা হবে যে তারা সংরক্ষণ না করা ডেটা সহ ফর্মটি সত্যই রেখে যেতে চান?



3
: এখানে এই প্রশ্নের উত্তর আপনি পরে থাকেন থাকা উচিত stackoverflow.com/questions/1244535/...
Nexerus


1
সম্পর্কিত: stackoverflow.com/q/821011/435605
AlikElzin-kilaka

উত্তর:


556

সংক্ষিপ্ত, ভুল উত্তর:

আপনি ইভেন্টটি পরিচালনা করে beforeunloadএবং একটি নন-স্ট্রিং ফিরে দিয়ে এটি করতে পারেন :

window.addEventListener("beforeunload", function (e) {
    var confirmationMessage = 'It looks like you have been editing something. '
                            + 'If you leave before saving, your changes will be lost.';

    (e || window.event).returnValue = confirmationMessage; //Gecko + IE
    return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});

এই পদ্ধতির সাথে সমস্যা হ'ল ফর্ম জমা দেওয়ার ফলে আনলোড ইভেন্টটিকেও ছড়িয়ে দেওয়া হচ্ছে । আপনি কোনও ফর্ম জমা দিচ্ছেন এমন পতাকা যুক্ত করে এটি সহজেই ঠিক করা হয়েছে:

var formSubmitting = false;
var setFormSubmitting = function() { formSubmitting = true; };

window.onload = function() {
    window.addEventListener("beforeunload", function (e) {
        if (formSubmitting) {
            return undefined;
        }

        var confirmationMessage = 'It looks like you have been editing something. '
                                + 'If you leave before saving, your changes will be lost.';

        (e || window.event).returnValue = confirmationMessage; //Gecko + IE
        return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
    });
};

তারপরে জমা দেওয়ার সময় সেটারকে কল করুন:

<form method="post" onsubmit="setFormSubmitting()">     
    <input type="submit" />
</form>

তবে পড়ুন ...

দীর্ঘ, সঠিক উত্তর:

ব্যবহারকারী যখন আপনার ফর্মগুলিতে কোনও পরিবর্তন করেনি তখন আপনি এই বার্তাটিও প্রদর্শন করতে চান না । একটি সমাধান হ'ল beforeunloadইভেন্টটি "নোংরা" পতাকার সাথে একত্রে ব্যবহার করা , যা প্রম্পটটিকে সত্যই প্রাসঙ্গিক হলে ট্রিগার করে।

var isDirty = function() { return false; }

window.onload = function() {
    window.addEventListener("beforeunload", function (e) {
        if (formSubmitting || !isDirty()) {
            return undefined;
        }

        var confirmationMessage = 'It looks like you have been editing something. '
                                + 'If you leave before saving, your changes will be lost.';

        (e || window.event).returnValue = confirmationMessage; //Gecko + IE
        return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
    });
};

এখন বাস্তবায়ন করতে isDirty পদ্ধতিটি জন্য বিভিন্ন পদ্ধতি রয়েছে।

আপনি jQuery এবং ফর্ম সিরিয়ালাইজেশন ব্যবহার করতে পারেন , তবে এই পদ্ধতির কিছু ত্রুটি রয়েছে। প্রথমে আপনাকে যে কোনও ফর্মের কাজ করতে কোডটি পরিবর্তন করতে $("form").each()হবে ( করবে) তবে সবচেয়ে বড় সমস্যাটি হল যে jQuery serialize()কেবল নামযুক্ত, অ-অক্ষম উপাদানগুলিতে কাজ করবে, সুতরাং কোনও অক্ষম বা নামবিহীন উপাদান পরিবর্তন করা ময়লা পতাকাটি ট্রিগার করবে না। তার জন্য কার্যকারিতা রয়েছে , যেমন সক্রিয় করার পরিবর্তে পাঠ্যভাবে নিয়ন্ত্রণ তৈরি করা, সিরিয়ালাইজ করা এবং তারপরে আবার নিয়ন্ত্রণগুলি অক্ষম করা।

সুতরাং ইভেন্টগুলি যাওয়ার পথে মনে হচ্ছে। আপনি কিপ্রেস শোনার চেষ্টা করতে পারেন । এই ইভেন্টটিতে কয়েকটি সমস্যা রয়েছে:

  • চেকবক্স, রেডিও বোতাম বা মাউস ইনপুট দ্বারা পরিবর্তন করা হচ্ছে এমন অন্যান্য উপাদানগুলিতে ট্রিগার করবেন না।
  • Ctrlকী এর মতো অপ্রাসঙ্গিক কীপ্রেসগুলির জন্য ট্রিগার করবে ।
  • জাভাস্ক্রিপ্ট কোডের মাধ্যমে সেট মানগুলিতে ট্রিগার করবে না।
  • প্রসঙ্গ মেনুগুলির মাধ্যমে পাঠ্য কাটা বা আটকানোতে ট্রিগার করবেন না।
  • ডেটপিকারস বা চেকবক্স / রেডিওবোটন বিউটিফায়ারগুলির মতো ভার্চুয়াল ইনপুটগুলির জন্য কাজ করবে না যা জাভাস্ক্রিপ্টের মাধ্যমে কোনও লুকানো ইনপুটে তাদের মান সংরক্ষণ করে।

changeঘটনা আরো জাভাস্ক্রিপ্ট কোড থেকে সেট মান উপর আরম্ভ না ভার্চুয়াল ইনপুট জন্য কাজ না করবে না, তেমনি।

inputinputtextareaselectআপনার পৃষ্ঠার সমস্ত (এবং গুলি এবং গুলি) এর সাথে ইভেন্টটি আবদ্ধ করা পুরানো ব্রাউজারগুলিতে কাজ করবে না এবং উপরে উল্লিখিত সমস্ত ইভেন্ট হ্যান্ডলিং সমাধানগুলির মতো, পূর্বাবস্থাকে সমর্থন করে না। যখন কোনও ব্যবহারকারী একটি পাঠ্যবক্স পরিবর্তন করে এবং তারপরে এটি পূর্বাবস্থায় ফিরে যায়, বা চেকবক্সটি চেক করে এবং আনচেক করে, তখনও ফর্মটি নোংরা বলে মনে করা হয়।

এবং যখন আপনি আরও কিছু আচরণ কার্যকর করতে চান, যেমন নির্দিষ্ট উপাদানগুলিকে উপেক্ষা করার মতো, আপনার আরও কাজ করার দরকার পড়ে।

চাকা পুনরায় উদ্ভাবন করবেন না:

সুতরাং এই সমাধানগুলি এবং প্রয়োজনীয় সমস্ত কাজের বাস্তবায়ন সম্পর্কে ভাবার আগে আপনি বুঝতে পারবেন যে আপনি চাকাটি পুনর্নবীকরণ করছেন এবং অন্যরা ইতিমধ্যে আপনার সমস্যার সমাধান করে নিয়েছে।

যদি আপনার অ্যাপ্লিকেশনটি ইতিমধ্যে jQuery ব্যবহার করে থাকে তবে আপনি নিজের ঘূর্ণায়মানের পরিবর্তে পরীক্ষিত, রক্ষণাবেক্ষণ কোডও ব্যবহার করতে পারেন এবং এগুলির জন্য একটি তৃতীয় অংশের লাইব্রেরি ব্যবহার করতে পারেন। jQuery এর আপনি কি নিশ্চিত? প্লাগইন দুর্দান্ত কাজ করে, তাদের ডেমো পৃষ্ঠাটি দেখুন । এটি এর মতোই সহজ:

<script src="jquery.are-you-sure.js"></script>

<script>
  $(function() {
    $('#myForm').areYouSure(
      {
        message: 'It looks like you have been editing something. '
               + 'If you leave before saving, your changes will be lost.'
      }
    );
  });

</script>

কাস্টম বার্তা সর্বত্র সমর্থিত নয়

মনে রাখবেন যে ফায়ারফক্স 4 এই ডায়ালগটিতে কাস্টম বার্তাগুলি সমর্থন করে না। এপ্রিল ২০১ of পর্যন্ত, ক্রোম ৫১ রোল আউট হচ্ছে যেখানে কাস্টম বার্তাগুলিও সরানো হচ্ছে

কিছু বিকল্প এই সাইটে অন্য কোথাও বিদ্যমান, তবে আমি মনে করি এর মতো একটি ডায়ালগ যথেষ্ট পরিষ্কার:

আপনি কি এই সাইটটি ছেড়ে যেতে চান?

আপনার করা পরিবর্তনগুলি সংরক্ষিত নাও হতে পারে।

Leave Stay


6
নোট করুন যে কাস্টম স্ট্রিংগুলি ব্যবহার করে Chrome এ আর কাজ করে না; chromestatus.com/feature/5349061406228480
amann

5
হ্যাঁ, এটি আমার উত্তরের শেষ অংশে বর্ণিত।
কোডকাস্টার

2
@ ক্রিসটি হ'ল কারণ অ্যাংুলার বর্তমান ডকুমেন্ট থেকে দূরে নেভিগেশন না করে পৃষ্ঠা পরিবর্তন করার জন্য ডিওএমকে চালিত করছে।
কোডকাস্টার

15
হতে সতর্ক jQuery এর areYouSure 2014 (57 খোলা বিষয় যেহেতু পরিত্যক্ত হয়েছে গিটহাব ), এটা আমার অভিজ্ঞতা থেকে বাগ পূর্ণ, এটি মনে হতে পারে মত এটা প্রথমে কাজ করে কিন্তু কিছু দ্রুত পরীক্ষার পর আমি এটা সবসময় কাজ করে না অনুভব করেছিল। এটি একেবারেই সুপারিশ করবে না
চিহ্নিত করুন

4
পছন্দ করেছেন @ জ্যাকোপোস্টাঞ্চি আমি দুর্ভাগ্যক্রমে কোনও পাইনি। এবং আমি বলতে চাইছি আমি অনেকটা দেখেছি - তবে এটি 10 ​​জানুয়ারিতে ফিরে এসেছে যাতে কেউ কিছু লিখেছিল তবে আমি সন্দেহ করি doubt আপনার সেরা বাজি এটি নিজেই প্রয়োগ করা - আপনি যা দুঃখিত তা শুনতে চান তা নয়। (তবে কমপক্ষে আপনি কোনও চমক পাবেন না যেমন আমি jQuery আর ইউসুওর ব্যবহার করেছিলাম Plus) প্লাস কে জানেন যে আপনি সম্ভবত এটি উন্মুক্ত উত্সও বানাতে পারেন এবং আপনার প্রয়োগ অন্যদের সাথে ভাগ করে নেওয়া হবে;)
মার্ক

75

জাভাস্ক্রিপ্টটি পুনরায় ডাউনলোড করুন ইভেন্টটি দেখুন । এটি মাইক্রোসফ্ট দ্বারা প্রবর্তিত নন-স্ট্যান্ডার্ড জাভাস্ক্রিপ্ট, তবে এটি বেশিরভাগ ব্রাউজারগুলিতে কাজ করে এবং তাদের অনবিত্ত ডাউনলোড ফাইলের ডকুমেন্টেশনে আরও তথ্য এবং উদাহরণ রয়েছে।


3
আমি মনে করি এটি এখন মানদণ্ডে পরিণত হয়েছে। >> ইভেন্টটি মূলত মাইক্রোসফ্ট দ্বারা ইন্টারনেট এক্সপ্লোরার 4 এ প্রবর্তিত হয়েছিল এবং এইচটিএমএল 5 নির্দিষ্টকরণে মানক করা হয়েছিল।
ভি

34

jquery মাধ্যমে

$('#form').data('serialize',$('#form').serialize()); // On load save form current state

$(window).bind('beforeunload', function(e){
    if($('#form').serialize()!=$('#form').data('serialize'))return true;
    else e=null; // i.e; if form state change show warning box, else don't show it.
});

আপনি গুগল জিকুয়েরি ফর্ম সিরিয়ালাইজ ফাংশন করতে পারেন, এটি সমস্ত ফর্ম ইনপুট সংগ্রহ করবে এবং এটি অ্যারেতে সংরক্ষণ করবে। আমি অনুমান করি এই ব্যাখ্যা যথেষ্ট যথেষ্ট :)


6
ফর্ম আইডি হিসাবে # ফর্মটি ব্যবহার করবেন না কারণ উইন্ডো নামটি ফর্ম তৈরি করবে এবং অবজেক্ট করবে :)
এমডিকিচি

1
: এখানে চেক করুন এটি আপনার জন্য কাজ করছে না stackoverflow.com/questions/7080269/...
Leniel Maccaferri

16

সর্বজনীন সমাধানের জন্য এমন কোনও কনফিগারেশনের প্রয়োজন নেই যা কনটেস্টেবলযোগ্য উপাদানগুলি সহ সমস্ত ইনপুট পরিবর্তনটি স্বয়ংক্রিয়ভাবে সনাক্ত করে:

"use strict";
(() => {
const modified_inputs = new Set;
const defaultValue = "defaultValue";
// store default values
addEventListener("beforeinput", (evt) => {
    const target = evt.target;
    if (!(defaultValue in target || defaultValue in target.dataset)) {
        target.dataset[defaultValue] = ("" + (target.value || target.textContent)).trim();
    }
});
// detect input modifications
addEventListener("input", (evt) => {
    const target = evt.target;
    let original;
    if (defaultValue in target) {
        original = target[defaultValue];
    } else {
        original = target.dataset[defaultValue];
    }
    if (original !== ("" + (target.value || target.textContent)).trim()) {
        if (!modified_inputs.has(target)) {
            modified_inputs.add(target);
        }
    } else if (modified_inputs.has(target)) {
        modified_inputs.delete(target);
    }
});
// clear modified inputs upon form submission
addEventListener("submit", () => {
    modified_inputs.clear();
    // to prevent the warning from happening, it is advisable
    // that you clear your form controls back to their default
    // state after submission
});
// warn before closing if any inputs are modified
addEventListener("beforeunload", (evt) => {
    if (modified_inputs.size) {
        const unsaved_changes_warning = "Changes you made may not be saved.";
        evt.returnValue = unsaved_changes_warning;
        return unsaved_changes_warning;
    }
});
})();

1
শীতল মটরশুটি. এই কোডটি কেবল আপনার পরীক্ষার পৃষ্ঠাতে আটকান অনুলিপি করুন, পরিবর্তন করুন এবং রিফ্রেশ করুন। এটি কোনও নেটিভ ব্রাউজার সতর্কতা প্রদর্শন করবে যাতে সতর্ক করে দেয় যে আপনার কাছে সংরক্ষিত পরিবর্তন রয়েছে।
দ্য লিজেন্ডারিকপি কোডার

1
এটি আমার জন্য ক্রোম 71.0.3578.98 (অফিসিয়াল বিল্ড) (
-৪

2
এটি সত্যই ভাল কাজ করে, তবে আপনি যদি জমা দেওয়ার জন্য কোনও ফর্মটি ব্যবহার করে থাকেন তবে আপনাকে প্রথমে সেটযুক্ত সংশোধিত_পুটগুলি সাফ করতে হবে অন্যথায় আপনি একটি নিশ্চিত পরিবর্তন সতর্কতা পাবেন। আমি জমা দেওয়ার জন্য আমার ফর্মটিতে একটি ইভেন্ট শ্রোতা যুক্ত করেছি, এবং কেবল সেট ফাংশনটি পরিষ্কার করে চালিয়েছি, আগে যখন ডাউনলোড লোড ইভেন্ট শ্রোতা চালিত হয় তখন পরিবর্তিত ইনপুটগুলি পরিষ্কার হয় এবং পোস্ট চালিয়ে যাওয়ার অনুমতি দেয়।
পদক্ষেপ 2

1
কুল আসলে কপি এবং পেস্ট করুন। আমার সময় বাঁচানোর জন্য ধন্যবাদ ফিরফক্স 75.0
সংযুক্তি_ ব্যবহারকারী

1
এই স্নিপেটটি পছন্দ করুন
কাঁচা বার্নার

10

সিরিয়ালাইজেশন ব্যবহারের জন্য ওয়াসিম এ এর দুর্দান্ত ধারণা শীর্ষে নির্মিত । সমস্যাটি হ'ল ফর্মটি জমা দেওয়ার সময় সতর্কতাটিও দেখানো হয়েছিল। এটি এখানে স্থির করা হয়েছে।

var isSubmitting = false

$(document).ready(function () {
    $('form').submit(function(){
        isSubmitting = true
    })

    $('form').data('initial-state', $('form').serialize());

    $(window).on('beforeunload', function() {
        if (!isSubmitting && $('form').serialize() != $('form').data('initial-state')){
            return 'You have unsaved changes which will not be saved.'
        }
    });
})

এটি ক্রোম এবং আইই 11 তে পরীক্ষা করা হয়েছে।


ওয়াসিম এ এবং এরিক সোভেন পিউডিস্ট - ধন্যবাদ আমি আমার সেভ বোতামটির জন্য ফর্ম এবং আইডির জন্য আইডি ব্যবহার করেছি কারণ আমার সমস্ত বোতাম জমা ছিল <ফর্ম ক্রিয়া = "" আইডি = "মার্কসফর্ম" পদ্ধতি = "পোস্ট"> <টি> <ইনপুট টাইপ = "জমা দিন" নাম = "দাখিল_বাটন" আইডি = "সংরক্ষণ" মান = "সংরক্ষণ"> </ strong> <td> <ইনপুট টাইপ = "জমা" নাম = "জমা দিন_বাটন" মান = "পরবর্তী"> </td> এবং কয়েকটি আরও সব ধরণের জমা তাই প্রতিস্থাপন করা হয়েছে। জমা দিন (নির্দিষ্ট ক্লিক করে $ ('# সংরক্ষণ করুন')। ক্লিক করুন (ফাংশন () {সাম্মিটিং = সত্য}) 'ফর্ম'-এর পরিবর্তে' # চিহ্নফর্ম 'ব্যবহার করুন
জয়ন্ত

7

পূর্ববর্তী উত্তরের উপর ভিত্তি করে এবং স্ট্যাক ওভারফ্লোতে বিভিন্ন জায়গা থেকে একত্রে আবদ্ধ হয়ে, আমি এখানে এসেছি এমন একটি সমাধান যা আপনি আসলে আপনার পরিবর্তনগুলি জমা দিতে চাইলে কেসটি পরিচালনা করে:

window.thisPage = window.thisPage || {};
window.thisPage.isDirty = false;

window.thisPage.closeEditorWarning = function (event) {
    if (window.thisPage.isDirty)
        return 'It looks like you have been editing something' +
               ' - if you leave before saving, then your changes will be lost.'
    else
        return undefined;
};

$("form").on('keyup', 'textarea', // You can use input[type=text] here as well.
             function () { 
                 window.thisPage.isDirty = true; 
             });

$("form").submit(function () {
    QC.thisPage.isDirty = false;
});
window.onbeforeunload = window.thisPage.closeEditorWarning;

এটি লক্ষণীয় যে IE11 এর জন্য closeEditorWarningফাংশনটি undefinedকোনও সতর্কতা না দেখানোর জন্য এটির জন্য ফিরে আসা দরকার বলে মনে হয় ।


এই সমাধানটি যাচাই করে না যে কোনও মান তাদের মূল অবস্থা থেকে পরিবর্তিত হয়েছে, এর ফলে অবৈধ হয়ে যায় যে ব্যবহারকারী পাঠ্য প্রবেশ করিয়ে দেয় এবং নেভিগেট করার চেষ্টা করার আগে সেই ইনপুটযুক্ত পাঠ্যটিকে মুছে দেয়।
ব্রেট ওয়েবার

ভাল পয়েন্ট, @ ব্র্যাটওয়েবার। আপনি সেক্ষেত্রে ক্লোজএডিটর ওয়ার্নিংটি সংশোধন করতে পারেন এবং "if (উইন্ডো.থিসপেজ.আইএসডিটি অ্যান্ড অ্যান্ডহাইসচ্যাঞ্জড ())" থাকতে পারেন, যেখানে uiHasChanged এমন একটি ফাংশন যা সার্ভার থেকে মূল অবস্থা সম্পর্কে জানে এবং সমস্ত পার্থক্য পরীক্ষা করে, তবে এই সমাধানটি ছিল এর জন্য এমন একটি ক্ষেত্রে যেখানে আমি বিশেষত সমস্ত অতিরিক্ত কাজটি করতে চাইনি, এবং এটি কেবলমাত্র মিথ্যা ইতিবাচক প্রভাব ফেলতে পারে যখন টেক্সারিয়াসে আসল কীগুলি তৈরি করা হয়েছিল, যা আমি মনে করি যে এটি একটি যুক্তিসঙ্গত আপস ছিল। :)
জোনাথন

না করা উচিত QC.thisPage.isDirty = false;হবে window.thisPage.isDirty = false;? এই পদ্ধতিতে, আপনি ফর্মটি জমা দিচ্ছেন কিনা এবং কোনও সতর্কতা প্রদর্শন করা হচ্ছে না তা এটি পরীক্ষা করবে। আমার পরীক্ষার জন্য কাজ করা বলে মনে হচ্ছে। এছাড়াও, বেশিরভাগ ফর্মের একটি inputপরিবর্তে একটি থাকে textarea। আমি নিম্নলিখিতগুলি ব্যবহার করেছি যা বরং ভাল কাজ করে:$("form").on('keyup', 'textarea,input,select', function () {
মাইক

7

নিম্নলিখিত ওয়ান-লাইনার আমার পক্ষে কাজ করেছে।

window.onbeforeunload = s => modified ? "" : null;

শুধু সেট modifiedকরার সত্য বা মিথ্যা আপনার আবেদনের রাষ্ট্র উপর নির্ভর করে।


2
কিছু পরামর্শ: খালি স্ট্রিংয়ের পরিবর্তে একটি কাস্টম বার্তা ফেরান কারণ কিছু ব্রাউজার এটি প্রদর্শন করবে (যেমন এজ) এবং ফিরে আসবে undefined বদলে nullযেমন অর্থাৎ 'নাল' প্রিন্ট হবে যদি modifiedমিথ্যা।
কেভিন লি

1
কিভাবে মোবাইল ডিভাইস সম্পর্কে? আমার বোধগম্যতা হল যে আইওএস ডিভাইসগুলি পূর্বেই ডাউনলোডের সম্মান দেয় না।
জায়েব্রো

4

নিম্নলিখিত কোড দুর্দান্ত কাজ করে। আপনাকে আইডি বৈশিষ্ট্যের মাধ্যমে আপনার ফর্ম উপাদানগুলির ইনপুট পরিবর্তনগুলি পৌঁছাতে হবে:

var somethingChanged=false;
            $('#managerForm input').change(function() { 
                somethingChanged = true; 
           }); 
            $(window).bind('beforeunload', function(e){
                if(somethingChanged)
                    return "You made some changes and it's not saved?";
                else 
                    e=null; // i.e; if form state change show warning box, else don't show it.
            });
        });

3
var unsaved = false;
$(":input").change(function () {         
    unsaved = true;
});

function unloadPage() {         
    if (unsaved) {             
        alert("You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?");
    }
} 
window.onbeforeunload = unloadPage;

আমি এটিকে একটি পৃথক ফাইলে সন্নিবেশ করলাম এবং আমি এটি <স্ক্রিপ্ট src = "चेतावनीOnChange.js"> </script> সহ অন্তর্ভুক্ত করেছি তবে যখন আমি একটি পাঠ্যক্ষেত্র পরিবর্তন করি এবং তখন আমি একটি শিরোনাম কমান্ড কার্যকর করি তখন কিছুই হয় না।
ফ্যাব্রিজিও বার্টোলোমুচি

2

আপনি ফর্মের মানগুলি সিরিয়ালাইজ করে URL এনকোডযুক্ত পাঠ্য স্ট্রিং তৈরি করতে সিরিয়ালাইজ () ব্যবহার করতে পারেন এবং ফর্মটি পূর্বেই পরিবর্তন হয়েছে কিনা তা পরীক্ষা করতে পারেন

$(document).ready(function(){
    var form = $('#some-form'),
        original = form.serialize()

    form.submit(function(){
        window.onbeforeunload = null
    })

    window.onbeforeunload = function(){
        if (form.serialize() != original)
            return 'Are you sure you want to leave?'
    }
})

ভ্লাদিমির সিডোরেনকো রচিত https://coderwall.com/p/gny70a/alert-when-leaving-page-with-unsaved-for এই লিঙ্কটি দেখুন


1
এটি কাজ করেছে, তবে কোড কাস্টারের জবাব অনুসারে, এই পদ্ধতির সাথে কিছু ত্রুটি রয়েছে, এই ব্যাখ্যাটি দেখুন stackoverflow.com/a/7317311/10555981
প্রদীপ

ইতিমধ্যে বেশ কয়েকটি উত্তর ব্যবহার করে আছে serialize()এবং প্রকৃতপক্ষে এর কমতি রয়েছে।
কোডকাস্টার

এটি সঠিক উত্তর হওয়া উচিত, ব্যবহার করা খুব সহজ এবং প্রত্যাশার মতো কাজ করে।
Jodyshop

1

@ কোডেকাস্টারের ধারণার সাথে যুক্ত করে আপনি এটি প্রতিটি ফর্মের সাথে প্রতিটি পৃষ্ঠায় যুক্ত করতে পারেন (আমার ক্ষেত্রে আমি এটি বিশ্বব্যাপী উপায়ে ব্যবহার করি যাতে কেবল ফর্মগুলিতেই এই সতর্কতা থাকতে পারে) তার ফাংশনটি এতে পরিবর্তন করে

if ( formSubmitting || document.getElementsByTagName('form').length == 0) 

এছাড়াও লগইন সহ জমা ফর্মগুলি এবং বোতামগুলির লিঙ্কগুলি বাতিল করে রাখুন যাতে কোনও ব্যক্তি যখন ফর্ম বাতিল বা জমা দেওয়ার জন্য চাপায় তখন প্রতিটি পৃষ্ঠায় সতর্কতাটিকেও একটি ফর্মের সাথে ট্রিগার করবে না ...

<a class="btn btn-danger btn-md" href="back/url" onclick="setFormSubmitting()">Cancel</a>

1

আপনি এখানে বিশদ ব্যাখ্যার জন্য যাচাই করতে পারেন: http : //techin exploifications.redexp.in/compistance-of-form-values-on-load-and-before-close/ তুলনা অফ ফর্ম-মান-অন-লোড-এবং -before-ঘনিষ্ঠ

প্রধান কোড:

function formCompare(defaultValues, valuesOnClose) {

    // Create arrays of property names
    var aPropsFormLoad = Object.keys(defaultValues);
    var aPropsFormClose = Object.keys(valuesOnClose);

    // If number of properties is different,
    // objects are not equivalent
    if (aPropsFormLoad.length != aPropsFormClose.length) {
        return false;
    }

    for (var i = 0; i < aPropsFormLoad.length; i++) {
        var propName = aPropsFormLoad[i];

        // If values of same property are not equal,
        // objects are not equivalent
        if (defaultValues[aPropsFormLoad]+"" !== valuesOnClose[aPropsFormLoad]+"") {
            return false;
        }
    }

    // If we made it this far, objects
    // are considered equivalent
    return true;

}

//add polyfill for older browsers, as explained on the link above

//use the block below on load
    for(i=0; i < document.forms[0].elements.length; i++){
    console.log("The field name is: " + document.forms[0].elements[i].name +
        " and it’s value is: " + document.forms[0].elements[i].value );
    aPropsFormLoad[i] = document.forms[0].elements[i].value;
    }

//create a similar array on window unload event.

//and call the utility function
    if (!formCompare(aPropsOnLoad, aPropsOnClose))
    {
    //perform action: 
    //ask user for confirmation or
    //display message about changes made
    }


1

এরিক সোভেন পিউডিস্টের সমাধান ...

var isSubmitting = false;

$(document).ready(function () {
    $('form').submit(function(){
        isSubmitting = true
    })

    $('form').data('initial-state', $('form').serialize());

    $(window).on('beforeunload', function() {
        if (!isSubmitting && $('form').serialize() != $('form').data('initial-state')){
            return 'You have unsaved changes which will not be saved.'
        }
    });
})

... স্বতঃস্ফূর্তভাবে আমার জন্য কোনও জটিল অবজেক্ট-ভিত্তিক সেটিংয়ে কোনও পরিবর্তন ছাড়াই প্রয়োজনীয় কাজটি করেছে।

আমি প্রয়োগ করা একমাত্র পরিবর্তনটি হ'ল "ফর্মফর্ম" ('ফর্ম' -> '# ফর্মফর্ম') নামক কংক্রিট ফর্ম (ফাইলের প্রতি কেবল একটি ফর্ম) উল্লেখ করুন:

<form ... id="formForm" name="formForm" ...>

সাবমিট বাটনটি "একা একা ছেড়ে" চলেছে এই বিষয়টি বিশেষ করে ভালভাবে করা হয়েছে।

অতিরিক্তভাবে, এটি ফায়ারফক্সের সর্বশেষতম সংস্করণ (ফেব্রুয়ারী 7, 2019 হিসাবে) নিয়েও আমার পক্ষে কাজ করে।


1

এলি গ্রে-এর সার্বজনীন সমাধানের পরীক্ষা করেছেন, আমি কোডটি সহজ করার পরে কেবল কাজ করেছি

  'use strict';
  (() => {
    const modified_inputs = new Set();
    const defaultValue = 'defaultValue';
    // store default values
    addEventListener('beforeinput', evt => {
      const target = evt.target;
      if (!(defaultValue in target.dataset)) {
        target.dataset[defaultValue] = ('' + (target.value || target.textContent)).trim();
      }
    });

    // detect input modifications
    addEventListener('input', evt => {
      const target = evt.target;
      let original = target.dataset[defaultValue];

      let current = ('' + (target.value || target.textContent)).trim();

      if (original !== current) {
        if (!modified_inputs.has(target)) {
          modified_inputs.add(target);
        }
      } else if (modified_inputs.has(target)) {
        modified_inputs.delete(target);
      }
    });

    addEventListener(
      'saved',
      function(e) {
        modified_inputs.clear()
      },
      false
    );

    addEventListener('beforeunload', evt => {
      if (modified_inputs.size) {
        const unsaved_changes_warning = 'Changes you made may not be saved.';
        evt.returnValue = unsaved_changes_warning;
        return unsaved_changes_warning;
      }
    });

  })();

তার পরিবর্তনগুলি target[defaultValue]কেবলমাত্র এবং শুধুমাত্র ব্যবহারের ব্যবহার মুছে ফেলা হয়েছেtarget.dataset[defaultValue] আসল ডিফল্ট মান সঞ্চয় করতে হয়।

এবং আমি একটি 'সংরক্ষিত' ইভেন্ট শ্রোতা যুক্ত করেছি যেখানে আপনার সংরক্ষণের ক্রিয়াকলাপটি সফল হওয়াতে 'সংরক্ষিত' ইভেন্টটি নিজের দ্বারা ট্রিগার করা হবে।

তবে এই 'সর্বজনীন' সমাধানটি কেবল ব্রাউজারগুলিতে কাজ করে, অ্যাপের ওয়েবভিউতে কাজ করে না, উদাহরণস্বরূপ, উইচ্যাট ব্রাউজারগুলি।

এটি উইচ্যাট ব্রাউজারগুলিতেও কাজ করতে (আংশিক), আবার আরও একটি উন্নতি:

  'use strict';
  (() => {
    const modified_inputs = new Set();
    const defaultValue = 'defaultValue';
    // store default values
    addEventListener('beforeinput', evt => {
      const target = evt.target;
      if (!(defaultValue in target.dataset)) {
        target.dataset[defaultValue] = ('' + (target.value || target.textContent)).trim();
      }
    });

    // detect input modifications
    addEventListener('input', evt => {
      const target = evt.target;
      let original = target.dataset[defaultValue];

      let current = ('' + (target.value || target.textContent)).trim();

      if (original !== current) {
        if (!modified_inputs.has(target)) {
          modified_inputs.add(target);
        }
      } else if (modified_inputs.has(target)) {
        modified_inputs.delete(target);
      }

      if(modified_inputs.size){
        const event = new Event('needSave')
        window.dispatchEvent(event);
      }
    });

    addEventListener(
      'saved',
      function(e) {
        modified_inputs.clear()
      },
      false
    );

    addEventListener('beforeunload', evt => {
      if (modified_inputs.size) {
        const unsaved_changes_warning = 'Changes you made may not be saved.';
        evt.returnValue = unsaved_changes_warning;
        return unsaved_changes_warning;
      }
    });

    const ua = navigator.userAgent.toLowerCase();

    if(/MicroMessenger/i.test(ua)) {
      let pushed = false

      addEventListener('needSave', evt => {
        if(!pushed) {
          pushHistory();

          window.addEventListener("popstate", function(e) {
            if(modified_inputs.size) {
              var cfi = confirm('确定要离开当前页面嘛?' + JSON.stringify(e));
              if (cfi) {
                modified_inputs.clear()
                history.go(-1)
              }else{
                e.preventDefault();
                e.stopPropagation();
              }
            }
          }, false);
        }

        pushed = true
      });
    }

    function pushHistory() {
      var state = {
        title: document.title,
        url: "#flag"
      };
      window.history.pushState(state, document.title, "#flag");
    }
  })();

0

আমি এটিকে এখানে আলাদাভাবে ভাগ করেছিলাম যাতে কেউ সহায়তা পেতে পারে, কেবল Chrome এর মাধ্যমে পরীক্ষা করা হয়।

আমি যদি কিছু পরিবর্তন হয় তবে ট্যাবটি বন্ধ করার আগে ব্যবহারকারীকে সতর্ক করতে চেয়েছিলাম।

<input type="text" name="field" value="" class="onchange" />

var ischanged = false;

$('.onchange').change(function () {
    ischanged = true;
});

window.onbeforeunload = function (e) {
    if (ischanged) {
        return "Make sure to save all changes.";
    }        
};

ভাল কাজ করে, তবে একটি অনন্য সমস্যা পেয়েছে, যখন আমি ফর্মটি জমা দিই আমি অযাচিত সতর্কতা পেয়েছি, আমি এতে প্রচুর পরিমাণে কাজ করতে দেখেছি, এটি কারণ হ'ল অনসামিতের আগে আগুন জ্বালানো কেন আমরা অনসামিত ইভেন্টে এটি পরিচালনা করতে পারি না onbeforeunload = null, তবে এই উভয় ইভেন্টের আগে জমা দেওয়ার বোতামে আগুন লাগার অন্লিক ইভেন্ট, তাই আমি কোডটি আপডেট করেছি

var isChanged = false;
var isSubmit = false;

window.onbeforeunload = function (e) {
    if (isChanged && (!isSubmit)) {
        return "Make sure to save all changes.";
    }        
};

$('#submitbutton').click(function () {
    isSubmit = true;
});

$('.onchange').change(function () {
    isChanged = true;
});

-5

প্রথমত, বেশিরভাগ ব্রাউজারের ডিফল্টরূপে এই ফাংশন থাকে। এবং কেন আপনার এ আদৌ দরকার? ফর্ম সিঙ্ক করবেন না কেন? মানে, ব্যবহারকারীর কাছ থেকে জমা দেওয়ার অপেক্ষা না করে কোনও পরিবর্তন এটিকে সংরক্ষণ করুন। গুগল পরিচিতিগুলির মতো। অবশ্যই যদি ফর্মের সমস্ত ক্ষেত্র বাধ্যতামূলক হয়। ব্যবহারকারীরা যখন তাদের প্রয়োজন হয় কিনা তা ভেবে দেখার সুযোগ ছাড়াই কোনও কিছু পূরণ করতে বাধ্য করে না। :)


আপনি কি ঠিক বলেছেন তবে আমার ফর্মগুলি গতিশীলভাবে উত্পন্ন হয়েছে এবং ক্ষেত্রগুলি আমার নিয়ন্ত্রণে নেই তাই আমার পক্ষে সমস্ত ক্ষেত্র সন্ধান করা এবং এজ্যাক্সের মাধ্যমে অনুরোধ প্রেরণ করা সম্ভব নয়, যদি আপনার মনে কিছু থাকে তবে দয়া করে আমার সাথে ভাগ করুন।
খান

ঠিক আছে এটি আপনার প্রয়োজনের জন্য প্রয়োজনীয় নাও হতে পারে তবে এটি এখনও কার্যকর হতে সক্ষম। ফর্ম উপাদানগুলি যদি স্ক্রিনে থাকে তবে আপনি নিজের ইভেন্ট ইভেন্ট হ্যান্ডলারগুলি সংযুক্ত করতে পারেন এবং যে কোনও ডেটা চান তা পেতে পারেন। তারপরে আপনি যেখানে পছন্দ করেন সেখানে ডেটা সংরক্ষণ করতে AJAX ব্যবহার করুন। এমনকি ফর্মগুলির এলোমেলোভাবে আইডি বা শ্রেণীর নাম উত্পন্ন হয়েছে, আপনি যদি ফর্মের কাঠামোটি অনুমান করতে পারেন তবে আপনি এক্সপ্যাথ ব্যবহার করতে পারেন। এটা কি এক্সএমএল / এইচটিএমএল ঠিক আছে? সুতরাং আপনি গতিশীলভাবে উত্পন্ন ফর্মের জন্য দায়ী ব্যক্তিদের সাথে একটি জেএডিও রাখতে পারেন এবং এই প্রকল্পে এক্সএসটিএল আপনাকে উভয়কে কীভাবে উপকৃত করতে পারে সে সম্পর্কে কথা বলতে পারেন। কেবল একটি চিন্তা ...
সাইমনডেভার

1
save it on any change without waiting any submitting from userআপনি সবসময় এটি করতে চান না। কখনও কখনও ব্যবহারকারী অনেকগুলি পরিবর্তন করে তারপরে পর্যালোচনা করে নিশ্চিত করতে চান যে তারা এটি সংরক্ষণ করতে চান।
BadHorsie

1
আমি ফর্মটি জমা দেওয়ার পরামর্শ দিইনি। ডেটা লোকালস্টোরারেজে কিছু ক্যাশে বা এমনকি কিছু খসড়া পতাকা সহ জমা দেওয়া যেতে পারে। এই আচরণের জন্য অনেকগুলি পদ্ধতি রয়েছে। তিনি ফর্মটি শেষ করেননি এবং উইন্ডোটি বন্ধ না করে এবং পরবর্তী সময় এটি আবার পূরণ করতে হবে সে সম্পর্কে ব্যবহারকারীকে সতর্ক করার চেয়ে এটি আরও ভাল। "আসুন, মনুষ্য, অলস হবেন না, আপনার ট্রেন / বাস / বিমান / ইত্যাদির মতো কিছু আসে যায় না, তেমনি আমাদের কোনও যত্ন নেই যে আপনি আপনার ল্যাপটপ থেকে কোনও চার্জার ভুলে গেছেন, কেবল এই জঘন্য ফর্মটি পূরণ করুন!"
ইউসু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.