javascript - OnBeforeUnload iletişim kutusunu nasıl geçersiz kılabilir ve kendi iletişim kutumla değiştirebilirim?


Kullanıcıları bir sayfayı terk etmeden önce kaydedilmemiş değişiklikler hakkında uyarmam gerekiyor (bu oldukça yaygın bir sorun).

window.onbeforeunload = handler

Bu işe yarıyor ama kendi metnimi saran can sıkıcı standart bir mesajla varsayılan bir iletişim kutusu açıyor. Metnim net olsun diye ya standart mesajı tamamen değiştirmem gerekiyor ya da (daha da iyisi) tüm iletişim kutusunu jQuery kullanarak modal bir iletişim kutusuyla değiştirmek.

Şimdiye kadar başarısız oldum ve cevabı olan gibi görünen başka birini bulamadım. Bu gerçekten mümkün mü?

Sayfamda Javascript:

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

closeIt() fonksiyonu:

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

jQuery ve jqModal kullanarak bu tür bir şeyi denedim (özelleştirilmiş bir onay diyaloğu kullanarak):

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

bu da işe yaramıyor - beforeunload olayına bağlanamıyor gibi görünüyorum.

Cevap #1

Güncelleme 09/04/2018: onbeforeunload diyaloglarındaki özel mesajlar chrome-51'den itibaren kullanımdan kaldırılmıştır (bkz: sürüm notu, MDN)


onbeforeunload için varsayılan diyaloğu değiştiremezsiniz, bu yüzden en iyi şansınız onunla çalışmak olabilir.

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

İşte Microsoft'tan bununla ilgili bir referans:

Bir dize, window.event öğesinin returnValue özelliğine atandığında, kullanıcıların mevcut sayfada kalma ve ona atanan diziyi koruma seçeneğini veren bir iletişim kutusu görüntülenir. İleti kutusunda görünen varsayılan ifade olan "Bu sayfadan ayrılmak istediğinizden emin misiniz? ... Devam etmek için Tamam'a, mevcut sayfada kalmak için İptal'e basın." kaldırılamaz veya değiştirilemez.

Sorun şu gibi görünüyor:

  1. onbeforeunload çağrıldığında, işleyicinin dönüş değerini window.event.returnValue olarak alacaktır.
  2. Daha sonra dönüş değerini bir dize olarak ayrıştıracaktır (eğer null değilse).
  3. Çünkü false bir dize olarak ayrıştırıldığından, iletişim kutusu tetiklenecek ve ardından uygun bir true/false iletilecektir.

Sonuç olarak, varsayılan iletişim kutusunu engellemek için onbeforeunload'a false atamanın bir yolu görünmüyor.

jQuery hakkında ek notlar:

  • jQuery'de eventi ayarlamak sorunlu olabilir, çünkü bu diğer onbeforeunload eventlerinin de gerçekleşmesine izin verir. Yalnızca kendi unload eventinizin gerçekleşmesini istiyorsanız, bunun için sade JavaScript kullanmanızı öneririm.

  • jQuery'nin onbeforeunload için bir kısayolu yok, bu yüzden genel bind sözdizimini kullanmanız gerekecek.

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

Cevap #2

Benim için işe yarayan, jQuery kullanarak ve IE8, Chrome ile Firefox'ta test edilen şey şudur:

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

Hiçbir istem gerekmediğinde hiçbir şey döndürmemek önemlidir, çünkü burada IE ile diğer tarayıcı davranışları arasında farklar vardır.

Cevap #3

Bazı durumlarda kutu hakkında yapabileceğiniz hiçbir şey olmasa da, birinin bir bağlantıya tıklamasını engelleyebilirsiniz. Benim için, bu çaba çoğu senaryo için değerdi ve yedek olarak, unload olayını bıraktım.

Standart jQuery Diyaloğu yerine Boxy kullandım, buradan ulaşabilirsiniz: 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.';
    }
};

Başka bir olaya bağlanabilir ve hangi türde bir çapa tıklandığını daha fazla filtreleyebilirsiniz, ancak bu benim için ve yapmak istediklerim için işe yarıyor ve başkalarının kullanması veya geliştirmesi için bir örnek olarak hizmet ediyor. Bu çözümü isteyenler için paylaşmak istedim.

Kodu kestim, bu yüzden bu olduğu gibi çalışmayabilir.

İlgili makaleler