2009-05-29 13 views
20

Co próbuję osiągnąć, to ostrzec użytkownika o niezapisanych zmianach, jeśli spróbuje zamknąć stronę lub odejść od niej bez uprzedniego zapisania.Aktywowanie TYLKO OnFefore przy zmianie wartości pól

Udało mi się otworzyć okno dialogowe OnBeforeUnload() ... ale nie chcę, aby było ono wyświetlane, jeśli użytkownik nie zmodyfikował żadnych wartości pól. W tym celu używam tego ukrytego pola wejściowego o nazwie is_modified, które zaczyna się od wartości domyślnej false i zmienia się na true, gdy dowolne pole jest edytowane.

Próbowałem powiązać zdarzenie zmienić do tego pola jest zmodyfikowane, aby spróbować wykryć zmianę wartości ... i tylko wtedy aktywować OnBeforeUnload.

$('#is_modified').change(function() { 
    if($('#is_modified').val() == 'true') 
     window.onbeforeunload = function() { return "You have unsaved changes."; } 
}); 

Ale z tego co mi zrozumieć to, że zdarzenie change() działa dopiero po tych 3 krokach - pole odbiera skupić wartość zostanie zmieniona, a pole traci ostrość. W przypadku ukrytego pola wejściowego nie jestem pewien, jak działa ta funkcja odbierania i utraty ostrości! Dlatego funkcja onbeforeunload nigdy nie jest aktywowana.

Czy ktokolwiek może sugerować sposób na utrzymanie spustu na poziomie jest zmodyfikowany?

Dzięki.

Odpowiedz

1

Wypróbuj swoją logikę w inny sposób. Znaczenie: ustaw logikę dla sprawdzania wartości pola wejściowego w metodzie onbeforeunload.

window.onbeforeunload = function() { 
    if ($("#is_modified").val() == 'true') { 
     return "You have unsaved changes."; 
    } else { 
     return true; // I think true is the proper value here 
    } 
}; 
+1

"true" nie jest prawidłową wartością. W niektórych przeglądarkach (przynajmniej Firefox, może więcej) zwracanie "null" spowoduje anulowanie okna dialogowego. Howerver, w IE, nie mogłem znaleźć sposobu na anulowanie okna dialogowego z poziomu obsługi. Jedyną rzeczą, która zadziałała, było całkowite usunięcie programu obsługi (np. "Window.beforeunload = null"), jak w odpowiedzi Bryana Larsena. –

+0

Wystarczająco fair. Niestety, nie sprawdziłem dokładnie mojego rozwiązania, zanim odpowiedziałem. :( –

+5

Wiem, że trochę się spóźniłem na imprezę, ale właśnie na to wpadłem, jednak w IE, jeśli funkcja zwraca 'undefined' (lub nic nie zwraca), okno dialogowe nie pokazuje się (działa również w FF) .Próbowałem zwracając true/false/null, a IE po prostu wstawił "true"/"false"/"null" jako tekst w oknie dialogowym.Nie ma pojęcia dlaczego.Myślę, że to pomaga komuś innemu. –

0

dlaczego nie ma połączenia onbeforeunload funkcję, która sprawdza, czy wartości uległy zmianie, a jeśli tak zwrotu „niezapisane zmiany” potwierdzić?

7

Po prostu używamy Window.onbeforeunload jako naszej flagi "zmienionej". Oto, co robimy, (używając lowpro):

Event.addBehavior({ 
    "input[type=radio]:change,input[type=text]:change,input[type=checkbox]:change,select:change": function(ev) { 
     window.onbeforeunload = confirmLeave; 
    } 
    ".button.submit-button:click": function(ev) { 
     window.onbeforeunload = null; 
    }, 
}); 


function confirmLeave(){ 
    return "Changes to this form have not been saved. If you leave, your changes will be lost." 
} 
+1

Wygląda na to, że ustawienie 'onbeforeunload = null' kończy się niepowodzeniem w IE: http://bustedmug.blogspot.com/2007/01/onbeforeunload-ie7-assigning-event.html –

+0

Wygląda na to, że to IE7 - tylko błąd - działa dobrze w IE8, co jest wszystkim, co muszę wesprzeć, na szczęście! –

0

w IE9 można używać prostych instrukcji return (RE), które nie będą wyświetlane żadne okno dialogowe. szczęśliwy kodowania ..

29

miałem podobny wymóg więc wymyślił poniższego skryptu jQuery:

$(document).ready(function() { 
    needToConfirm = false; 
    window.onbeforeunload = askConfirm; 
}); 

function askConfirm() { 
    if (needToConfirm) { 
     // Put your custom message here 
     return "Your unsaved data will be lost."; 
    } 
} 

$("select,input,textarea").change(function() { 
    needToConfirm = true; 
}); 

Powyższy kod sprawdza zmienną needToConfirm, jeśli jej true następnie wyświetli komunikat ostrzegawczy. Po każdej zmianie wartości elementów elementu needToConfirm jest ustawiana na true.


PS: Firefox> 4 nie pozwalają na niestandardową wiadomość dla onbeforeunload.
referencyjny: https://bugzilla.mozilla.org/show_bug.cgi?id=588292


UPDATE: Jeśli jesteś maniakiem wydajność, pokochasz @KyleMit's sugestię. Napisał rozszerzenie jQuery only(), które zostanie wykonane tylko raz dla dowolnego elementu.

$.fn.only = function (events, callback) { 
    //The handler is executed at most once for all elements for all event types. 
    var $this = $(this).on(events, myCallback); 
    function myCallback(e) { 
     $this.off(events, myCallback); 
     callback.call(this, e); 
    } 
    return this 
};  

$(":input").only('change', function() { 
    needToConfirm = true; 
}); 
+0

Działa jak urok, ale jest mały problem: nie mogę zmienić komunikatu. Chciałbym napisać własna wiadomość typu: "Czy zwariowałeś, że chcesz odejść?", ale nie mogłam go uruchomić ... – marianobianchi

+0

@marianobianchi: Zaktualizowałem swoją odpowiedź. – xyz

+0

Dzięki za odpowiedź, ale okazało się, że problem był inny. Używam firefox i istnieje funkcja, która nie pozwala zmienić tej wiadomości. Próbuję go w chrome i działa, ale nie będzie działał w firefox ... – marianobianchi

5

Poniższe działa dobrze w jQuery:

var needToConfirm = false; 

$("input,textarea").on("input", function() { 
    needToConfirm = true; 
}); 

$("select").change(function() { 
    needToConfirm = true; 
}); 

window.onbeforeunload = function(){   
    if(needToConfirm) { 
    return "If you exit this page, your unsaved changes will be lost.";   
    } 
} 

A jeśli użytkownik próbuje wysłać formularz, aby zapisać zmiany, warto dodać ten (zmiana #mainForm do identyfikatora formularza oni „re złożenie):

$("#mainForm").submit(function() { 
    needToConfirm = false; 
}); 
2
$(window).bind('beforeunload',function() { 
return "'Are you sure you want to leave the page. All data will be lost!"; 
}); 

$('#a_exit').live('click',function() { 
    $(window).unbind('beforeunload'); 
}); 

Przede pracuje dla mnie.

Powiązane problemy