Kaydedilmemiş değişikliklerle web sayfasından ayrılmadan önce kullanıcıyı uyar


341

Başvurumda formları olan bazı sayfalar var.

Formu, birisi tarayıcı sekmesinden ayrılırsa veya kapatırsa, formu gerçekten kaydedilmemiş verilerle terk etmek istediklerini onaylamaları istenecek şekilde nasıl güvenceye alabilirim?



3
Bu soruya şu sorunun cevabını vermelisiniz: stackoverflow.com/questions/1244535/…
Nexerus


Yanıtlar:


556

Kısa, yanlış cevap:

Bunu , beforeunloadolayı işleyip boş olmayan bir dize döndürerek yapabilirsiniz :

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.
});

Bu yaklaşımdaki sorun, form göndermenin de boşaltma olayını tetiklemesidir . Bu, bir form gönderdiğiniz bayrak ekleyerek kolayca giderilir:

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.
    });
};

Sonra gönderirken ayarlayıcıyı arayın:

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

Ama okuyun ...

Uzun, doğru cevap:

Kullanıcı, formlarınızda hiçbir şey değiştirmediğinde de bu mesajı göstermek istemezsiniz . Çözümlerden biri, beforeunloadolayı yalnızca gerçekten ilgili olduğunda istemi tetikleyen "kirli" bir bayrakla birlikte kullanmaktır .

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.
    });
};

Şimdi isDirtyyöntemi uygulamak için çeşitli yaklaşımlar var.

JQuery ve form serileştirmeyi kullanabilirsiniz , ancak bu yaklaşımın bazı kusurları vardır. Öncelikle kodu herhangi bir form üzerinde çalışacak şekilde değiştirmeniz gerekir ( $("form").each()yapacak), ancak en büyük sorun jQuery'nin serialize()yalnızca adlandırılmış, devre dışı olmayan öğeler üzerinde çalışacağıdır, bu nedenle herhangi bir devre dışı veya adlandırılmamış öğeyi değiştirmek kirli bayrağı tetiklemez. Bunun için geçici çözümler var kontrolleri etkinleştirmek, serileştirmek ve sonra tekrar devre dışı bırakmak yerine kontrolleri salt okunur yapmak gibi .

Yani olaylar gidilecek yol gibi görünüyor. Tuşlara basmayı dinlemeyi deneyebilirsiniz . Bu etkinliğin birkaç sorunu var:

  • Onay kutuları, radyo düğmeleri veya fare girişi ile değiştirilen diğer öğeler üzerinde tetiklenmez.
  • CtrlAnahtar gibi alakasız tuş basışlarını tetikler .
  • JavaScript kodu ile ayarlanan değerlerde tetiklenmez.
  • Bağlam menüleri aracılığıyla metin kesmeyi veya yapıştırmayı tetiklemez.
  • Datepickers veya onay kutusu / radyo düğmesi güzelleştiricileri gibi değerlerini JavaScript aracılığıyla gizli bir girişe kaydeden sanal girişler için çalışmaz.

changeOlay da JavaScript kodundan belirlenen değerlere tetiklemez yüzden de, sanal girişler için olmaz işi.

Bağlama inputtüm olay inputs (ve textareas ve selects) sayfanızda olmaz eski tarayıcılarda çalışması tüm olay işleme çözümleri gibi ve, geri alma desteklemez, yukarıda bahsedilen. Kullanıcı bir metin kutusunu değiştirip geri alırsa veya bir onay kutusunu işaretleyip işaretini kaldırırsa, form hala kirli kabul edilir.

Ve belirli unsurları göz ardı etmek gibi daha fazla davranış uygulamak istediğinizde, daha da fazla işiniz olacak.

Tekerleği yeniden icat etmeyin:

Dolayısıyla, bu çözümleri ve gerekli tüm geçici çözümleri uygulamayı düşünmeden önce, tekerleği yeniden icat ettiğinizi ve başkalarının sizin için zaten çözdüğü sorunlarla karşılaşmaya eğilimli olduğunuzu anlayın.

Uygulamanız zaten jQuery kullanıyorsa, kendi yuvarlamak yerine test edilmiş, bakımı yapılmış bir kod kullanabilir ve bunların tümü için bir üçüncü bölüm kitaplığı kullanabilirsiniz. jQuery Emin misiniz? eklenti harika çalışıyor, demo sayfalarına bakın . Bu kadar basit:

<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>

Her yerde desteklenmeyen özel mesajlar

Firefox 4'ün bu iletişim kutusunda özel mesajları desteklemediğini unutmayın . Nisan 2016 itibarıyla, özel mesajların da kaldırıldığı Chrome 51 kullanıma sunuldu .

Bu sitenin başka yerlerinde bazı alternatifler var, ancak bunun gibi bir iletişim kutusunun yeterince açık olduğunu düşünüyorum:

Bu siteden ayrılmak istiyor musunuz?

Yaptığınız değişiklikler kaydedilemeyebilir.

Leave Stay


6
Özel dizelerin kullanılmasının Chrome'da artık çalışmadığını unutmayın; chromestatus.com/feature/5349061406228480
amann

5
Evet, bu cevabımın son bölümünde anlatıldı.
CodeCaster

2
@Chris, Angular'ın geçerli belgeden uzaklaşmadan sayfayı değiştirmek için DOM'u manipüle etmesi nedeniyle olacak.
CodeCaster

15
Uyarısında jQuery areYouSure 2014 (57 açık sorun beri terk edilmiş Be Github ilk başta çalışıyor ancak bazı hızlı testlerden sonra ben her zaman işi değil fark gibi), benim deneyimlerinden böcek dolu, öyle görünebilir. Bunu hiç tavsiye etmem
Mark

4
@JacopoStanchi Maalesef hiç bulamadım. Demek istediğim çok fazla baktım - ama 10 Ocak'ta geri döndü, bu yüzden birisi bir şeyler yazmış olabilir ama bundan şüpheliyim. En iyi bahsiniz bunu kendiniz uygulamaktır - bu kadar üzgün olduğunuzu duymak istediğiniz şey değildir. (Ama en azından jQuery areYouSure kullanarak yaptığım gibi sürprizler elde edemezsiniz.) Artı belki de açık kaynak bile yapabileceğinizi ve uygulamanız başkalarıyla paylaşılacağını bilen;)
Mark

75

Yüklemeden önce JavaScript etkinliğine göz atın . Microsoft tarafından sunulan standart dışı bir JavaScripttir, ancak çoğu tarayıcıda çalışır ve önceden yüklenmemiş belgelerinde daha fazla bilgi ve örnek bulunur.


3
Şimdi standart haline geldiğini düşünüyorum. >> Etkinlik ilk olarak Microsoft tarafından Internet Explorer 4'te tanıtıldı ve HTML5 belirtiminde standart hale getirildi.
vee

34

jquery ile

$('#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.
});

Google JQuery Form Serileştirme işlevini kullanabilirsiniz, bu tüm form girdilerini toplar ve diziye kaydeder. Sanırım bu açıklama yeterli :)


6
#form form id olarak kullanmayın çünkü pencere form oluşturacak ve form adlı nesne oluşturacaktır :)
mdikici

1
Sizin için çalışmıyorsa buraya bakın: stackoverflow.com/questions/7080269/…
Leniel Maccaferri

16

İçeriği düzeltilebilir öğeler de dahil olmak üzere tüm giriş değişikliklerini otomatik olarak algılayan hiçbir yapılandırma gerektirmeyen evrensel çözüm:

"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
Serin fasulye. Sadece bu kodu test sayfanıza yapıştırın, bir değişiklik yapın ve yenile düğmesine basın. Kaydedilmemiş değişiklikleriniz olduğunu bildiren yerel bir tarayıcı uyarısı görüntüler.
TheLegendaryCopyCoder

1
Bu benim için Chrome 71.0.3578.98 (Resmi Derleme) (64 bit) üzerinde çalıştı
JacobRossDev

2
Bu gerçekten iyi çalışıyor, ancak bunu bir form göndermek için kullanıyorsanız, önce değiştirilmiş_input'ları temizlemeniz gerekir, aksi takdirde bir değişiklik onaylama uyarısı alırsınız. Gönderme çağrılmak için formuma bir olay dinleyicisi ekledim ve set işlevini açık bir şekilde çalıştırdım, bu şekilde değiştirilen_inputlar, ununload olay dinleyicisi çalıştığında ve postanın devam etmesine izin verdiğinde açıktır.
stepquick

1
Cool aslında kopyalayıp yapıştırın. zamanımı kurtardığın için teşekkürler. Firfox 75.0'da çalışın
Connectify_user

1
Bu pasajı seviyorum
Rawburner

10

Wasim A.'nin serileştirmeyi kullanma konusundaki mükemmel fikrinin üzerine inşa edilmiştir . Sorun, form gönderilirken de uyarının gösterilmesiydi. Bu burada düzeltildi.

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.'
        }
    });
})

Chrome ve IE 11'de test edilmiştir.


Wasim A ve Eerik Sven Puudist - Teşekkürler Tüm düğmelerim type send <form action = "" id = "marksform" method = "POST"> <td> <input type = "gönder" ad = "gönder daha bütün tip Dolayısıyla belirli tıklama $ ( 'save #') tarafından .Submit (değiştirilir submit yerine 'çifti halinde (function () {isSubmitting = true} Kullan '#marksform') tıklayın.
Jayanta

7

Önceki yanıtlara dayanarak ve yığın taşması içindeki çeşitli yerlerden birlikte taşlanmış, işte, değişikliklerinizi gerçekten göndermek istediğinizde davayı ele alan çözüm buldum:

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'in bir uyarı göstermemesi için closeEditorWarningişlevin geri dönmesini gerektirdiğini belirtmek gerekir undefined.


Bu çözüm, herhangi bir değerin orijinal durumundan değiştirildiğini doğrulamaz; bu nedenle, kullanıcının metin girmesi ve uzaklaşmaya çalışmadan önce girilen metni silmesi geçersiz olur.
Brett Weber

Güzel nokta, @BrettWeber. Bu durumda closeEditorWarning öğesini değiştirebilir ve "if (window.thisPage.isDirty && uiHasChanged ())" öğesine sahip olabilirsiniz; burada uiHasChanged, sunucudaki orijinal durumu bilen ve tüm farklılıkları kontrol eden bir işlevdir, ancak bu çözüm özellikle tüm bu ekstra işleri yapmak istemediğim bir durum, ve bu sadece makul bir uzlaşma olduğunu hissettiğim textareas gerçek tuş basımları yapıldığında yanlış pozitifleri var. :)
Jonathan

Gerekmiyor QC.thisPage.isDirty = false;olmak window.thisPage.isDirty = false;? Bu şekilde, formu gönderip göndermediğinizi kontrol eder ve bir uyarı göstermez. Testlerim için işe yarıyor gibiydi. Ayrıca, çoğu formda inputa yerine bir textarea. Oldukça iyi çalışan aşağıdakileri kullandım:$("form").on('keyup', 'textarea,input,select', function () {
Mike

7

Aşağıdaki tek astar benim için çalıştı.

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

Sadece set modifiediçin gerçek veya sahte uygulamanın durumuna bağlı olarak.


2
Bazı öneriler: Bazı tarayıcılar görüntüleyeceğinden (ör. Edge) boş bir dize yerine özel bir mesaj döndürün ve IE yanlışsa 'null' yazdıracağından undefinedziyade geri dönün . nullmodified
Kevin Lee

1
mobil cihazlara ne dersiniz? benim anlayışım, IOS cihazlarının yüksüz olarak onurlandırılmamasıdır.
jaybro

4

Aşağıdaki kod harika çalışıyor. Form öğelerinizin giriş değişikliklerine id niteliği üzerinden erişmeniz gerekir:

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;

Ayrı bir dosyaya ekledim ve <script src = "warnOnChange.js"> </script> ile ekledim, ancak bir metin alanını değiştirdiğimde ve sonra bir başlık komutu yürüttüğümde hiçbir şey olmuyor.
Fabrizio Bartolomucci

2

Form değerlerini serileştirerek URL kodlu metin dizesi oluşturmak ve serialize (formun yüklenmeden önce değişip değişmediğini kontrol etmek için serialize () kullanabilirsiniz.

$(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?'
    }
})

Bu bağlantıya bakın https://coderwall.com/p/gny70a/alert-when-leaving-page-with-unsaved-form Yazan Vladimir Sidorenko


1
Çalıştı, ancak kod tekeri tarafından yanıtlandığı gibi, bu yöntemle ilgili bazı kusurlar var, bu açıklamaya bakın stackoverflow.com/a/7317311/10555981
Pradeep

Zaten birkaç cevap var serialize()ve aslında dezavantajları var.
CodeCaster

Bu doğru cevap olmalı, kullanımı çok basit olmalı ve beklendiği gibi çalışmalıdır.
Jodyshop

1

@ Codecaster fikrini ekleyerek bir formla her sayfaya ekleyebilirsin (benim durumumda küresel şekilde kullanıyorum, böylece sadece formlarda bu uyarıda bulunacaktı) işlevini değiştirmek için

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

Ayrıca, giriş ve iptal düğmeleri bağlantılarını içeren formları gönderin, böylece kişi iptal et veya formu gönderdiğinde, form olmadan her sayfada uyarıyı tetiklemez ...

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

1

Ayrıntılı bir açıklama için buraya bakabilirsiniz : http://techinvestigations.redexp.in/comparison-of-form-values-on-load-and-before-close/ formdaki değerlerin karşılaştırılması bakılırsa-yakın

Ana kod:

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

Kısa cevap:

let pageModified = true

window.addEventListener("beforeunload", 
  () => pageModified ? 'Close page without saving data?' : null
)

1

Eerik Sven Puudist'in çözümü ...

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.'
        }
    });
})

... işi kendiliğinden karmaşık bir nesne yönelimli ortamda herhangi bir değişiklik yapmadan yaptı.

Uyguladığım tek değişiklik, "formForm" ('form' -> '#formForm') adı verilen somut forma (dosya başına yalnızca bir form) başvurmaktı:

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

Özellikle iyi yapılması, gönder düğmesinin "yalnız bırakılması" gerçeğidir.

Ayrıca, benim için de en son Firefox sürümü ile çalışıyor (7 Şubat 2019 itibariyle).


1

Eli Grey'in evrensel çözümü test edildi, ancak kodu basitleştirdikten sonra çalıştı

  '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;
      }
    });

  })();

Onun üzerinde yapılan değişiklikler target[defaultValue]sadece kullanımı ve kullanımı silinir.target.dataset[defaultValue] gerçek varsayılan değerin saklanması için .

Ve kaydetme işleminiz başarılı olduğunda 'kaydedilen' etkinliğin kendiniz tarafından tetikleneceği bir 'kaydedilmiş' olay dinleyicisi ekledim.

Ancak bu 'evrensel' çözüm yalnızca tarayıcılarda çalışır, uygulamanın web görünümünde, örneğin wechat tarayıcılarında çalışmaz.

Wechat tarayıcılarında (kısmen) çalışmasını sağlamak için, yine başka bir gelişme:

  '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

Farklı bir şekilde yaptım, burada paylaşarak birinin yardım alabilmesi için yalnızca Chrome ile test edildi.

Yalnızca bazı değişiklikler olduğunda sekmeyi kapatmadan önce kullanıcıyı uyarmak istedim.

<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.";
    }        
};

İyi çalışıyor, ama başka bir sorun var, ben istenmeyen uyarı olsun formu gönderdiğinizde, ben üzerinde geçici çözüm bir sürü gördüm, bunun nedeni onubforeload önce yangınlar neden bu gibi onubmit olay ele olamaz onbeforeunload = null, Gönder düğmesi onclick olayı her iki olaydan önce patlar, bu yüzden kodu güncelledi

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

Her şeyden önce, çoğu tarayıcı varsayılan olarak bu işleve sahiptir. Ve neden buna hiç ihtiyacınız var? Formu neden senkronize halde tutmuyorsunuz? Yani, kullanıcıdan herhangi bir göndermeyi beklemeden herhangi bir değişikliğe kaydedin. Google Kişiler gibi. Tabii ki sadece formdaki tüm alanlar zorunluysa. Kullanıcılar, bir şeye ihtiyaç duyup duymadıklarını düşünmeye başlamadan bir şeyi doldurmaya zorlandıklarından hoşlanmazlar. :)


haklısın, ancak formlarım dinamik olarak oluşturuldu ve alanlar benim kontrolümde değil, bu yüzden benim için tüm alanı izlemek ve ajax aracılığıyla istek göndermek mümkün değil, aklında bir şey varsa lütfen benimle paylaş.
Khan

Tamam, amaçlarınız için gerekli olmayabilir, ancak yine de uygulanabilir. Form öğeleri ekranda bulunuyorsa, kendi olay işleyicilerinizi ekleyebilir ve istediğiniz verileri alabilirsiniz. Ardından verileri istediğiniz yere kaydetmek için AJAX kullanın. Formlar rastgele oluşturulmuş kimliklere veya sınıf adlarına sahip olsa bile, formun yapısını tahmin edebiliyorsanız XPath'leri kullanabilirsiniz. XML / HTML değil mi? Böylece dinamik olarak oluşturulmuş formdan sorumlu kişilerle bir JAD bile olabilir ve XSTL'nin bu projede size nasıl fayda sağlayabileceği hakkında konuşabilirsiniz. Sadece bir düşünce ...
SimonDever

1
save it on any change without waiting any submitting from userBunu her zaman yapmak istemezsiniz. Bazen kullanıcı birçok değişiklik yapmak ve ardından kaydetmek istediğini gözden geçirip onaylamak ister.
BadHorsie

1
Formu göndermeyi önermedim. Veriler localStorage'a, bazı önbelleklere ve hatta bazı taslak bayraklarla gönderilebilir. Bu davranış için birçok yöntem vardır. Formu bitirmediği konusunda kullanıcıyı uyarmaktan daha iyidir ve pencereyi kapatıp kapatmayacaksa, bir dahaki sefere tekrar doldurması gerekecektir. "Hadi adamım, tembel olmayın, tren / otobüs / uçak / vb. Önemli değil, aynı zamanda dizüstü bilgisayarınızdan bir şarj cihazını unuttuğunuz umurumda değil, sadece bu lanet formu doldurun!"
YuS
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.