代码之家  ›  专栏  ›  技术社区  ›  Ben Everard

jqueryajax问题,间歇性地获得重复请求

  •  6
  • Ben Everard  · 技术社区  · 15 年前

    现在,我们的JavaScript系统的重写即将结束,我们将从原型转移到jQuery。我们有一堆AJAX请求,它们在某个元素事件发生时触发,下面示例中的一个是日历上的新事件,但它也发生在其他地方。

    我遇到的问题是我们的jqueryscreen拦截器被设置为在大量AJAX请求期间防止用户输入,显然是因为AJAX请求仍然存在,而屏幕永远不会解锁。如果我要刷新这个屏幕,所有的工作都将按预期进行。

    有人能解释为什么会发生这种行为吗。

    alt text http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request.png

    编辑

    好的,问题是当我点击refresh时,问题通常会自行解决,所以不确定这怎么可能是一个处理程序问题,下面是我们通常用于更改选择框的事件处理程序。

    $("#my_select","#context").change(function(){
                // uz_ajax is a wrapper function, keeps most of the same functionality as $.ajax()
        uz_ajax({
            target:"#my_target",
            data:{
                module:'my_module',
                controller:'my_controller',
                action:'my_action',
                id:$(this).val(),
                ajax:''
            }
        });
    });
    

    我的问题是我不知道如何复制这个问题,所以我不知道事件是否被多次触发,或者AJAX是否请求了两次。

    如果您正在重新加载 被递归触发。。。我们真的 需要看更多的代码(你做什么 关于ajax调用的成功等)

    感谢redsquare,在AJAX请求成功后,我通常会应用响应(通常是HTML) <option> uz_ajax 如下所示:

    var ajax_count = 0;
    var ajax_response = null;
    
    function uz_ajax(options) {
    
        // set default options
        var defaults = {
            async: true,
            type: "GET",
            data: {},
            url: "/",
            cache: false,
            force_change: true,
            highlight: true,
            action: "normal",
            dataType: "html",
            selected: {
                value: null,
                disabled: false
            }
        };
    
        // merge the passed options with the defaults
        var options = $.extend(defaults, options);
    
        // start the jQuery ajax method
        $.ajax({
            async: options.async,
            type: options.type,
            url: options.url,
            data: options.data,
            beforeSend: function() {
                // we only want to block the screen on the first pass
                if(++ajax_count==1) {
                    $.blockUI({message:'Loading data, please wait'});
                } 
            },
            success: function(responseText) {           
                if(options.target!==undefined) {
                    // if target isn't an array, make it one
                    if(!$.isArray(options.target)) {
                        options.target = new Array(options.target);
                    }
    
                    var targets = options.target;
    
                    for ( var i in targets ) {
                        console_info("uz_ajax() --> Applying contents to "+targets[i]);
    
                        switch(options.action) {
                            case "normal":
                                if($(targets[i]).is("input")) {
                                    $(targets[i]).val(trim(responseText));
                                } else {
                                    $(targets[i]).html(trim(responseText));
                                }
                                break;
                            case "selected":
                                // preserve the current target value (e.g. list of options), but 
                                // set the selected value to the ajax response
                                console_warn("Changing selected value of "+targets[i]+" to '"+responseText+"'");
                                // trim the response so we don't get any smarty induced errors such as '    7'
                                $(targets[i]).val(trim(responseText));
                                break;
                        }
    
                        // set selected value
                        if(options.selected.value!=null) {
                            $(targets[i]).val(options.selected.value);
                        }
    
                        // highlight the target
                        // we don't want to highlight the target if it's a hidden input, as this will force a .show(
                        if($(targets[i]).attr('type')!='hidden' && options.highlight===true) {
                            $(targets[i]).effect("highlight",{},2000);
                        }
    
                        // force the target to change
                        if(options.force_change===true) {
                            $(targets[i]).trigger("change");    
                        }
    
                        /* rebind certain elements that do not use conventional events */
                        /* We probably need to get all of these rebinds in a single function */
                        createDatePickers(targets[i]);
                    }
                } else {
                    ajax_response = responseText;
                    console_warn("uz_ajax -> no targets specified");
                    // Well... we have no element to target, we need to return the value instead
                    // of course if we return here we're going
                    // we probably also need to check the ajax count as this will be the last executed part before we return
                }
            },
            complete: function () {
                /* if all ajax requests have completed, unblock screen */
                if(--ajax_count===0) {
                    $.unblockUI();
                    /* could use this callBack to return a value *dun dun duuuuun* */
                    if (options.ajaxComplete) {
                        options.ajaxComplete(ajax_response);
                    }
                }
            },
            cache: options.cache,
            dataType: options.dataType
        });
    
    }
    

    阻止多个ajax的另一种方法 请求检查jQuery.active 打电话之前。jQuery保持 使用此属性。红方块

    我会调查的。

    所以这是$('element').data()的结果,但我不明白它想说什么,这是否意味着它有两个绑定。如果是这样的话,我如何找出这些绑定是什么,以及为什么在触发事件时它们都不触发。

    alt text http://archive.ilmv.co.uk/images/firebug-jquery-data-events.png

    这是问题的另一个截图,这次是在系统的另一个地方。绿色箭头是触发这三个ajax请求的元素,而不是firebug中的六个,它们配对并共享时间戳到毫秒?

    alt text http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request-v2.png

    不同的ajax请求。

    我已经设法进行了更多的调试,我可以告诉您以下内容:

    1. 不管初始元素调用了多少ajax请求,问题都会出现
    2. 这个事件肯定只会被触发一次
    3. 我加了一句 console.info $.ajax() 回调以查看什么正在启动以及何时启动,请注意如何启动唯一的回调 beforeSend() .

    alt text http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request-v3.png

    编辑6

    在@redsquare通过Twitter建议使用 console.trace() 为了找出“第二个事件从何处触发”,就像我一直坚持的那样,我确信没有两个事件触发,所以我将跟踪放在 $.ajax() 方法,事情是这样的:

    alt text http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request-v4.png

    如您所见,即使 方法只触发了一次,时间戳同样相同。我在jQuery中遇到错误了吗?

    编辑7

    它也发生在StackOverflow上!

    alt text http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request-v5.png

    4 回复  |  直到 15 年前
        1
  •  1
  •   Phil    15 年前

    您尝试过使用.click()吗?我在使用javascript中的.change()时遇到了不规则活动的问题。试试看。

        2
  •  1
  •   Ben Everard    15 年前

    是的,所以我得出了一个结论,我很确定我的问题是Firebug的问题,因为我已经测试了它,在FF上的应用程序没有Firebug打开,它工作正常。

    这不是JavaScript相关的东西第一次让我在问题引发的症状不能为解决方案提供任何合理的提示时高兴地跳起舞来,但我们已经做到了。

        3
  •  0
  •   jantimon    15 年前

    尝试添加 return false 到onchange函数。

    你应该确保 $("#my_select","#context").change(function(){

        4
  •  0
  •   Ngo Quang Duong    7 年前

    我试过了 this

    $(selector).unbind().on(eventname,function(){
        $.ajax({
            //ajax code here
        });
    });