2

私のページには、Ajax を使用する 2 つの要素があります。1 つは単純なチェックボックス (デフォルトを設定) で、もう 1 つはリンクによってトリガーされるポップアップ ウィンドウです。ポップアップ ウィンドウは多数の要素をロードする必要があるため、ajaxStart() によってトリガーされ、ajaxStop() で非表示になる「loading...」オーバーレイ div があります。

ajaxStart() 読み込みオーバーレイがチェックボックスとポップアップの両方でトリガーされることを除いて、すべて正常に機能します。私が望んでいないdivの素早い「フラッシュ」であるため、チェックボックスが面倒です。

私の質問: ページ上のすべての Ajax 対応要素ではなく、ページ上の特定の要素に対してのみ AjaxStart をトリガーするにはどうすればよいですか?


HTML

<input type="checkbox" id="defaultproject"  />
<a class="openDialog" data-dialog-id="subscriberDialog" data-dialog-title="Project Subscriber" href="/Project/CreateSubscriber/1020" id="newsubscriber">Add Subscriber</a>

Javascript

    //POPUP 
    $(document).ready(function () {
    $(".openDialog").live("click", function (e) {
        e.preventDefault();

        $("<div></div>")
            .addClass("dialog")
            .attr("id", $(this).attr("data-dialog-id"))
            .appendTo("body")
            .dialog({
                title: $(this).attr("data-dialog-title"),
                close: function () { location.reload() },
                modal: true,
                draggable: false,
                resizable: false,
                width: 500

            })
            .load(this.href);
    });

    $(".close").live("click", function (e) {
        e.preventDefault();
        $(this).closest(".dialog").dialog("close");
    });  


    //CHECKBOX
    $("#defaultproject").change(function () 
    {

     var isitchecked = document.getElementById("defaultproject").checked

     $.ajax({
        url: '@Url.Action("SetDefaultProject")',
        data:  {"id": ProjectId, "isitchecked": isitchecked },
        type: 'POST',
        cache: 'false',
        success: function (response) {
            document.getElementById("defaultproject").disabled = "disabled";
        },
        error: function (xhr) {
            alert('There was an error.  Please try again');
            document.getElementById("defaultproject").checked = ""
        }
    });

   });

    //SHOW LOADING DIV
    //*** THIS IS WHERE I'M HAVING PROBLEMS

    $('.openDialog').ajaxStart(function () {
        $('#loadingdiv').show();
    }).ajaxStop(function () {
        $('#loadingdiv').hide();
    });
4

3 に答える 3

3

なぜイベントを利用したいのですか?pop にのみ固有の場合は、コールバック関数を使用します。

$(".openDialog").live("click", function (e) {
    e.preventDefault();

    $('#loadingdiv').show();
    $("<div></div>")
        .addClass("dialog")
        .attr("id", $(this).attr("data-dialog-id"))
        .appendTo("body")
        .dialog({
            title: $(this).attr("data-dialog-title"),
            close: function () { location.reload() },
            modal: true,
            draggable: false,
            resizable: false,
            width: 500

        })
        .load(this.href,function(){
            $('#loadingdiv').hide();
        });
});
于 2012-06-02T17:27:30.667 に答える
1

jQuery は ajaxStart に何も渡していないようで、どの ajax リクエストが開始されたかを知ることができます。

したがって、ajaxStart ハンドラーで処理しようとするのではなく、ajax 呼び出しソースで区別を処理するのがおそらく最善です。

これは、グローバル変数を介して実現できます。次のようなグローバル変数を宣言します

 var checkBoxAjax = false;

次に、チェックボックスのajax呼び出しを配置する前にtrueにします

 $("#defaultproject").change(function () 
  {
   checkBoxAjax = true;

 var isitchecked = document.getElementById("defaultproject").checked

 $.ajax({
    url: '@Url.Action("SetDefaultProject")',
    data:  {"id": ProjectId, "isitchecked": isitchecked },
    type: 'POST',
    cache: 'false',
    success: function (response) {
        document.getElementById("defaultproject").disabled = "disabled";
    },
    error: function (xhr) {
        alert('There was an error.  Please try again');
        document.getElementById("defaultproject").checked = ""
    }
});

});

そしてあなたのajaxStartに次のようなチェックを追加してください

$('.openDialog').ajaxStart(function () {
    if(!checkBoxAjax)   
        $('#loadingdiv').show();
    else
        checkBoxAjax = false;
}).ajaxStop(function () {
    $('#loadingdiv').hide();
});
于 2012-06-02T17:05:20.600 に答える
1

ここでの問題は、ajax 呼び出しを特定の dom オブジェクトに結び付けることは、load 関数またはコンテキストが設定されている場合にのみ固有であることです。

そのため、タスク全体が決定論的ではありません。次の例を検討してください。

$.ajax({
   url: "example.com",
   success: function(response) {
       $('.openDialog').html(response);
   }
});

への呼び出しは options 引数内のどこにも$.ajax明示的に言及していないため、success 関数が html をロードするかどうかを判断することは不可能です。.openDialog

ただし、コンテキスト オブジェクトが設定されるたびにイベントをトリガーすることができます。これはあまり信頼できませんが、目的によっては問題ないかもしれません。

(function(ajax) {
    $.fn.ajax = function(options) {
        if (options.context) {
           $(options.context).trigger("ajaxLoadStart");

            return ajax.apply(this, arguments).then(function() {
               $(options.context).trigger("ajaxLoadEnd");
            });           
        }

        return ajax.apply(this, arguments);
    };   
})($.fn.ajax);

ajaxLoadStartこれで、 とにバインドできますajaxLoadEnd:

$(document).on("ajaxLoadStart", ".dialog", function () {
    $('#loadingdiv').show();
}).on("ajaxLoadEnd", ".dialog", function () {
    $('#loadingdiv').hide();
});

( deprecated$(document).on(event, selector, callback)と同じであることに注意してください) $(selector).live(event, callback);

これで、クラスを含む div がdialogのオプション オブジェクトにコンテキストとして含まれるたびに$.ajax、それがトリガーさajaxLoadStartれ、次にがトリガーされますajaxLoadEnd。私の知る限り、jQueryはそれぞれのオブジェクトに設定されたコンテキストで.load()内部的に呼び出します。$.ajax

アップデート

残念ながら、コンテキストで.loadは使用しません。$.ajaxしたがって、トリガーも次のようにアタッチする必要があります.load

(function(load) {
    $.fn.load = function(url, params, callback) {
        if ( typeof url !== "string")
            return load.apply(this, arguments);

        this.trigger("ajaxLoadStart");

        var done = (function(callback) {
            return function() {
                $(this).trigger("ajaxLoadEnd");

                if ($.isFunction(callback))
                    callback.apply(this, arguments);
            };
        })($.isFunction(params) ? params : callback);


        return load.call(this, url, $.isFunction(params) ? done : params, $.isFunction(callback) ? done : callback);
    };   
})($.fn.load);

これらのアダプターは両方とも、今のところ問題なく動作するはずです。ただし、jquery の内部動作が変更された場合、これは壊れやすい (イベントの二重トリガー) ため、jquery をアップグレードするたびにそれらを修正する必要がある場合。

于 2012-06-02T17:09:31.300 に答える