用 jQuery 手動觸發 onbeforeunload 事件

使用者填寫表單的時候,常常會手殘的點到不該點的,或是忘了自己在幹嘛,於是呢開發者們就必須要檢查使用者有沒有修改過表單,如果有的話在他們要離開網頁的時候跳個提醒跟他們說

1
你要放棄修改嗎?

等等類似的訊息…用 jQuery 習慣的人就會用下列的語法來實現

1
2
3
$(window).on('beforeunload', function() {
return '你要放棄修改嗎?';
});

但是事情永遠不是那麼簡單,在某些情況下,表單會是在 iframe 裡面,而在 iframe 裡面的表單在移除 iframe 的時候,並不會觸發 beforeunload 的事件…所以呢,就要開始來 hack 拉!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// $.dialog 只是個示意的 function
// dialog 是跳出來的 dialog 的 jQuery Object
var dialog = $.dialog({
title: 'Form edit',
url: '/form_edit',
onEscape: function() {
var iframe = dialog.find('iframe')[0];
var iframeWindow = iframe.contentWindow;
var unloadMessage = iframeWindow.$(iframeWindow).triggerHandler('beforeunload');
var cfm = null;
if (unloadMessage) {
cfm = confirm(unloadMessage);
if (!cfm) {
return false; // 阻止 dialog 關閉
}
}
}
}).show();

這邊最主要的就是 triggerHandler,一般常用的其實是 jQuery.trigger,但是 trigger 沒有辦法接收 handler 的返回值,而 triggerHandler 可以接收返回值,可以接收返回值就代表只會觸發第一個 handler 並且返回該 handler 的返回值,就不會再執行後續的動作了!