在beforeunload事件处理程序中停止卸载页面 [英] Stop page from unloading within the beforeunload event handler

查看:211
本文介绍了在beforeunload事件处理程序中停止卸载页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在用户导航之前,页面代码会检查他是否编辑了某些表单字段。如果他这样做,我会显示一个模态窗口,其中按钮。如果他单击否,则模态应该关闭,用户仍然在该窗口上。如果是 - 保存更改并卸载。

Before user navigates the page code checks if he edited some of the form fields. If he did, I display a modal window with Yes and No buttons. If he clicks no, modal should close and the user remains on that window. If yes - save changes and unload.

  $(window).bind('beforeunload', function(){
        // check if any field is dirty 
        if ($('div.form').dirtyForms('isDirty')) {
            var modalParams = {
                Content: 'You have some unsaved changes, proceed?'
                OnSave: navigateAndSave,
                OnCancel: cancelNavigate
            }
           ShowModal(modalParams);
        }
    })

function navigateAndSave() {
    // Do stuff
};

function cancelNavigate() {
    // Stop page from unloading and close the modal
};

那我该怎么办 cancelNavigate 来停止页面卸载?

So what can I do in cancelNavigate to stop the page from unloading?

推荐答案

这是可能的,但前提是用户单击页面中的超链接。如果用户使用浏览器导航离开页面,他们将获得默认的浏览器对话框,该对话框没有保存选项。

This is possible, but only if the user clicks a hyperlink within the page. If the user uses the browser to navigate away from the page, they will get the default browser dialog, which doesn't have an option to save.

Dirty Forms自动附加(并删除处理程序)到 beforeunload 事件,因此您创建另一个事件处理程序的尝试肯定会失败。在使用Dirty Forms时你永远不应该这样做。

Dirty Forms automatically attaches (and removes the handler) to the beforeunload event, so your attempt to create another event handler will most certainly fail. You should never do this when using Dirty Forms.

你没有提到你想要使用哪个模态对话框架,所以我将只使用jQuery UI对话框展示一个例子。集成其他对话框架是类似的。为此,您可能需要查看现有预建的源代码对话框

You didn't mention which modal dialog framework you wanted to use, so I will just show an example using jQuery UI dialog. Integrating other dialog frameworks is similar. To do so, you might want to check out the source code of the existing pre-built dialogs.

此外,您的用例有点短边。如果用户想要离开并忽略更改,该怎么办?我添加了一个示例,其中包含另外一个选项。

Also, your use case is a bit short-sided. What if the user wants to navigate away and ignore the changes? I have added an example that includes an additional option to do just that.

<html>
<head>
    <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/jquery.ui/1.11.3/jquery-ui.min.css" />
</head>
<body>

    <script type="text/javascript" src="//cdn.jsdelivr.net/g/jquery@1.11.3,jquery.ui@1.11.3,jquery.dirtyforms@2.0.0"></script>
    <script type="text/javascript">
    $(document).ready(function() {
        // This is required by jQuery UI dialog
        $('body').append('<div id="dirty-dialog" style="display:none;" />');

        // This must be called before the first call to .dirtyForms
        $(document).bind('bind.dirtyforms', function (ev, events) {
            var originalOnRefireClick = events.onRefireClick;

            events.onRefireClick = function (ev) {
                if (saveForm) {
                    // TODO: Replace this with your AJAX function
                    // to save the form.
                    alert('saving form...');
                }
                originalOnRefireClick(ev);
            };
        });

        // Flag indicating whether or not to save the form on close.
        var saveForm = false;

        $('.mainForm').dirtyForms({
            dialog: {
                // Custom properties to allow overriding later using 
                // the syntax $.DirtyForms.dialog.title = 'custom title';

                title: 'Are you sure you want to do that?',
                proceedAndSaveButtonText: 'Save Changes & Continue',
                proceedAndCancelButtonText: 'Cancel Changes & Continue',
                stayButtonText: 'Stay Here',
                preMessageText: '<span class="ui-icon ui-icon-alert" style="float:left; margin:2px 7px 25px 0;"></span>',
                postMessageText: '',
                width: 650,

                // Dirty Forms Methods
                open: function (choice, message) {
                    $('#dirty-dialog').dialog({
                        open: function () {
                            // Set the focus on close button. This takes care of the 
                            // default action by the Enter key, ensuring a stay choice
                            // is made by default.
                            $(this).parents('.ui-dialog')
                                   .find('.ui-dialog-buttonpane button:eq(2)')
                                   .focus();
                        },

                        // Whenever the dialog closes, we commit the choice
                        close: choice.commit,
                        title: this.title,
                        width: this.width,
                        modal: true,
                        buttons: [
                            {
                                text: this.proceedAndSaveButtonText,
                                click: function () {
                                    // Indicate the choice is the proceed action
                                    choice.proceed = true;

                                    // Pass a custom flag to indicate to save the data first
                                    // in the onRefireClick event
                                    saveForm = true;

                                    $(this).dialog('close');
                                }
                            },
                            {
                                text: this.proceedAndCancelButtonText,
                                click: function () {
                                    // Indicate the choice is the proceed action
                                    choice.proceed = true;
                                    // Pass a custom flag to indicate not to save the data
                                    // in the onRefireClick event
                                    saveForm = false;

                                    $(this).dialog('close');
                                }
                            },
                            {
                                text: this.stayButtonText,
                                click: function () {
                                    // We don't need to take any action here because
                                    // this will fire the close event handler and
                                    // commit the choice (stay) for us automatically.
                                    $(this).dialog('close');
                                }
                            }
                        ]
                    });

                    // Inject the content of the dialog using jQuery .html() method.
                    $('#dirty-dialog').html(this.preMessageText + message + this.postMessageText);
                },
                close: function () {
                    // This is called by Dirty Forms when the 
                    // Escape key is pressed, so we will close
                    // the dialog manually. This overrides the default
                    // Escape key behavior of jQuery UI, which would
                    // ordinarily not fire the close: event handler 
                    // declared above.
                    $('#dirty-dialog').dialog('close');
                }
            }
        });
    });
    </script>

    Change one of the fields below, then click "Go to Google" to try to navigate away.

    <form class="mainForm" action="jqueryui.html">
        First name: <input type="text" name="fname"><br>
        Last name: <input type="text" name="lname"><br>
        <input type="submit" value="Submit">
    </form>

    <a href="http://www.google.com/">Go to Google</a>

</body>
</html>

该示例使用自定义事件绑定附加到 onRefireClick 事件处理程序,该事件处理程序在 choice.proceed = true ,但不是 false

The example uses custom event binding to attach to the onRefireClick event handler, which is fired when choice.proceed = true, but not when it is false.

这篇关于在beforeunload事件处理程序中停止卸载页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆