2009-05-29 2 views
20

То, что я пытаюсь достичь, состоит в том, чтобы предупредить пользователя о несохраненных изменениях, если он пытается закрыть страницу или перейти от нее без сохранения в первую очередь.Активация OnBeforeUnload ТОЛЬКО при изменении значений полей

Мне удалось открыть диалоговое окно OnBeforeUnload() для всплывающего окна ... но я не хочу, чтобы он отображался вообще, если пользователь не изменил значения полей. Для этого я использую это скрытое поле ввода is_modified, которое начинается со значения по умолчанию false и переворачивается до true при редактировании любого поля.

Я попытался связать событие событие в это поле is_modified, чтобы попытаться обнаружить изменение значения ... и только затем активировать OnBeforeUnload.

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

Но от того, что я полагаю, что change() событие работает только после того, как эти 3 шага - поле получает фокус, значение изменяется, а поле теряет фокус. В случае скрытого поля ввода, я не уверен, как это происходит и теряется часть фокуса! Следовательно, функция onbeforeunload никогда не активируется.

Может ли кто-нибудь предложить способ поддержания триггера по is_modified?

Спасибо.

ответ

1

Попробуйте свою логику по-другому. Смысл, поставьте логику для проверки значения поля ввода в вашем методе 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" не является надлежащим значением. В некоторых браузерах (по крайней мере, Firefox, возможно, больше) возврат «null» отменяет диалог. Howerver, в IE, я не смог найти способ отменить диалог внутри обработчика. Единственное, что сработало для меня, - это удалить обработчик полностью заранее (например, «window.beforeunload = null»), как в ответе Брайана Ларсена. –

+0

Достаточно честный. К сожалению, я не тщательно тестировал свое решение, прежде чем ответить. :( –

+5

Я знаю, что я немного опоздал на вечеринку, но я просто наткнулся на это. Однако в IE, если функция возвращает 'undefined' (или ничего не возвращает), диалог не отображается (это также работает в FF). Я попытался вернуть true/false/null, и IE просто поместил бы «true»/«false»/​​«null» в качестве текста в диалоговом окне. Не знаю, почему. Надеюсь, это поможет кому-то еще. –

0

почему нет onbeforeunload вызова функции, которая проверяет, если значения изменились, и если да, вернуть «несохраненные изменения» подтвердить?

7

Мы используем только Window.onbeforeunload как наш «измененный» флаг. Вот то, что мы делаем, (используя 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

По-видимому, установка 'onbeforeunload = null' терпит неудачу в IE: http://bustedmug.blogspot.com/2007/01/onbeforeunload-ie7-assigning-event.html –

+0

Кажется, это IE7 - только ошибка - он отлично работает в IE8, и это все, что мне нужно, к счастью! –

0

в IE9 вы можете использовать простой оператор возврата (ре), которые не будут отображаться диалоговое окно. счастливым кодирования ..

29

У меня было подобное требование так придумали следующий скрипт 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; 
}); 

Приведенный выше код проверяет переменную needToConfirm, если его true то появится предупреждающее сообщение. Когда значение input, select или textarea изменяется, значение needToConfirm равно true.


PS: Firefox> 4 не позволяют пользовательское сообщение для onbeforeunload.
Ссылка: https://bugzilla.mozilla.org/show_bug.cgi?id=588292


UPDATE: Если вы урод производительность, вы будете любить @KyleMit's предложение. Он написал расширение jQuery only(), которое будет выполнено только один раз для любого элемента.

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

Это работает как прелесть. Но есть небольшая проблема: я не могу получить сообщение изменено. Я хотел бы написать свой личное сообщение вроде: «Ты сумасшедший, что хочешь уйти?», но я не мог заставить его работать ... – marianobianchi

+0

@marianobianchi: Я обновил свой ответ. – xyz

+0

Спасибо за ваш ответ, но я обнаружил, что проблема была другая. Я использую firefox, и есть функция, которая не позволяет изменить это сообщение. Я пробовал его в хроме, и он работал, но он не будет работать в firefox ... – marianobianchi

5

Следующие хорошо работает в 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.";   
    } 
} 

И если пользователь подав форму, чтобы сохранить изменения, вы можете добавить (изменить #mainForm идентификатору формы они «повторно представления):

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

Над работает для меня.

Смежные вопросы