20

典型的な Web アプリケーションがありますが、これは本質的に、ある程度複雑な画面がいくつかあるデータ入力アプリケーションです。ユーザーが「保存」ボタンをクリックするのを忘れてから移動したりブラウザを閉じたりすると、警告が表示され、キャンセルできるようにする標準機能を提供する必要があります (ただし、保存されていないデータやダーティなデータがある場合のみ)。

私は自分がしなければならないことの基本を知っています - 実際、私は何年も前にそれをすべてやったと確信しています (onbeforeunload に結び付け、ページの「ダーティ」状態を追跡するなど... )しかし、これをまだコーディングし始める前に、すでに出回っている(無料またはその他の)ライブラリについて、役立つ提案はありますか?

4

6 に答える 6

19

パズルのピース:

/**
 * Determines if a form is dirty by comparing the current value of each element
 * with its default value.
 *
 * @param {Form} form the form to be checked.
 * @return {Boolean} <code>true</code> if the form is dirty, <code>false</code>
 *                   otherwise.
 */
function formIsDirty(form)
{
    for (var i = 0; i < form.elements.length; i++)
    {
        var element = form.elements[i];
        var type = element.type;
        if (type == "checkbox" || type == "radio")
        {
            if (element.checked != element.defaultChecked)
            {
                return true;
            }
        }
        else if (type == "hidden" || type == "password" || type == "text" ||
                 type == "textarea")
        {
            if (element.value != element.defaultValue)
            {
                return true;
            }
        }
        else if (type == "select-one" || type == "select-multiple")
        {
            for (var j = 0; j < element.options.length; j++)
            {
                if (element.options[j].selected !=
                    element.options[j].defaultSelected)
                {
                    return true;
                }
            }
        }
    }
    return false;
}

そして別

window.onbeforeunload = function(e)
{
    e = e || window.event;  
    if (formIsDirty(document.forms["someFormOfInterest"]))
    {
        // For IE and Firefox
        if (e)
        {
            e.returnValue = "You have unsaved changes.";
        }
        // For Safari
        return "You have unsaved changes.";
    }
};

すべてをまとめると、何が得られますか?

var confirmExitIfModified = (function()
{
    function formIsDirty(form)
    {
        // ...as above
    }

    return function(form, message)
    {
        window.onbeforeunload = function(e)
        {
            e = e || window.event;
            if (formIsDirty(document.forms[form]))
            {
                // For IE and Firefox
                if (e)
                {
                    e.returnValue = message;
                }
                // For Safari
                return message;
            }
        };
    };
})();

confirmExitIfModified("someForm", "You have unsaved changes.");

beforeunloadのイベント登録を使用するように、イベント ハンドラーの登録も変更する必要があるでしょうLIBRARY_OF_CHOICE

于 2008-09-26T16:20:39.093 に答える
13

jQuery を使用している場合は、次の簡単な方法があります。

$('input:text,input:checkbox,input:radio,textarea,select').one('change',function() {
  $('BODY').attr('onbeforeunload',"return 'Leaving this page will cause any unsaved data to be lost.';");
});

ただし、このページからリダイレクトする条件がある場合、またはフォームの投稿を成功させたい場合は、リダイレクトまたは送信イベントの前に次のようにこれを行う必要があります。

$('BODY').removeAttr('onbeforeunload');

...または、プロンプトを求め続けるループに陥ります。

私の場合、私は大きなアプリを持っていて、Javascript で location.href リダイレクトを行っていました。フォームの投稿と同様に、いくつかの AJAX 送信を行ってから、ページにインラインで成功応答を返しました。これらの条件のいずれにおいても、そのイベントをキャプチャして removeAttr() 呼び出しを使用する必要がありました。

于 2009-04-10T05:37:54.237 に答える
8

Volomike の優れた jQuery コードを少し拡張したいと考えていました。

したがって、これにより、保存する前に更新されたデータから離れて移動することによる不注意なデータ損失を防ぐという目的を達成するための非常にクールでエレガントなメカニズムがあります。ページのフィールドを更新してから、[保存] ボタンをクリックする前に、ブラウザのボタン、リンク、または [戻る] ボタンをクリックします。

必要な作業は、更新されたデータを保存するか削除しないかのいずれかで、Web サイトにポストバックするすべてのコントロール (特に [保存] ボタン) に「noWarn」クラス タグを追加することだけです。

コントロールが原因でページのデータが失われた場合。次のページに移動するか、データを消去します。スクリプトによって警告メッセージが自動的に表示されるため、何もする必要はありません。

素晴らしい!よくやったボロミケ!

jQuery コードを次のように記述します。

$(document).ready(function() {

    //----------------------------------------------------------------------
    // Don't allow us to navigate away from a page on which we're changed
    //  values on any control without a warning message.  Need to class our 
    //  save buttons, links, etc so they can do a save without the message - 
    //  ie. CssClass="noWarn"
    //----------------------------------------------------------------------
    $('input:text,input:checkbox,input:radio,textarea,select').one('change', function() {
        $('BODY').attr('onbeforeunload',
        "return 'Leaving this page will cause any unsaved data to be lost.';");
    });

    $('.noWarn').click(function() { $('BODY').removeAttr('onbeforeunload'); });

});
于 2009-06-19T16:26:18.247 に答える
7

Lance の回答に加えて、このスニペットを実行するために午後を過ごしました。まず、jquery 1.4 には、change イベントのバインディングに関するバグがあるようです (2010 年 2 月現在)。jQuery 1.3 は問題ありません。第二に、jquery に onbeforeunload/beforeunload をバインドさせることができません (私が使用している IE7 が疑われます)。("body")、(window) など、さまざまなセレクターを試しました。「.bind」、「.attr」を試しました。純粋な js に戻すとうまくいきました (この問題について、SO に関するいくつかの同様の投稿も見ました)。

$(document).ready(function() {
    $(":input").one("change", function() {
        window.onbeforeunload = function() { return 'You will lose data changes.'; }
    });
    $('.noWarn').click(function() { window.onbeforeunload = null; });
});

すべての入力タイプを列挙するのではなく、「:input」セレクターも使用したことに注意してください。厳密にはやり過ぎですが、私はそれがクールだと思いました:-)

于 2010-02-08T07:18:19.123 に答える
2

Webアプリケーションの未保存の変更に関する警告機能を実装するために使用できるjQueryプラグインを作成しました。ポストバックをサポートします。onbeforeunloadまた、InternetExplorerのイベントの動作を正規化する方法に関する情報へのリンクも含まれています。

于 2010-03-31T20:36:57.813 に答える
1

このページにリストされている jQuery の実装に、もう 1 つわずかな改善を加えました。私の実装は、クライアント側の ASP.NET ページ検証が有効になっており、ページで使用されている場合に処理されます。

onBeforeLeave検証の失敗によりクリック時にページが実際に投稿されない場合に、関数をクリアする「エラー」を回避します。no-warn-validate検証を引き起こすボタン/リンクでクラスを使用するだけです。no-warn持っているコントロールで使用するクラスがまだありますCausesValidation=false(たとえば、「下書きとして保存」ボタン)。このパターンは、おそらく ASP.NET 以外の検証フレームワークにも使用できるので、参考のためにここに投稿します。

 function removeCheck() { window.onbeforeunload = null; }

$(document).ready(function() {
    //-----------------------------------------------------------------------------------------
    // Don't allow navigating away from page if changes to form are made. Save buttons, links,
    // etc, can be given "no-warn" or "no-warn-validate" css class to prevent warning on submit.
    // "no-warn-validate" inputs/links will only remove warning after successful validation
    //-----------------------------------------------------------------------------------------
    $(':input').one('change', function() {
        window.onbeforeunload = function() {
            return 'Leaving this page will cause edits to be lost.';
        }
    });

    $('.no-warn-validate').click(function() {
        if (Page_ClientValidate == null || Page_ClientValidate()) { removeCheck(); }
    });

    $('.no-warn').click(function() { removeCheck() });
});
于 2010-03-08T16:14:49.313 に答える