【问题标题】:Global Variable not affected in JQuery Ajax Success Function全局变量在 JQuery Ajax 成功函数中不受影响
【发布时间】:2019-07-18 07:05:40
【问题描述】:

我有一个递归函数,它填充一个列表,直到到达屏幕底部,然后停止。

每次调用递归函数时,“start”全局变量都会增加限制 (5)。例如,3 次后,“start”变量应该是 15。这在控制台中正确显示。

但是,在递归函数之外,“start”变量似乎仍为“0”。我认为在函数外部使用“var start = 0”会使其成为全局变量,应该由 Ajax 成功函数更改。代码如下:

//****************************************************************
//        Loading questions and answers listings
//****************************************************************
var tag = '';//initialize as blank
var search = '';//initialize as blank
var limit = 5;//number of records to autoload each time
var start = 0;//start at record 0
var action = 'inactive';//initial status to get initial load
var autoscroll = 'false';//check box to engage auto scroll or keep manual load more 
var checked = '';//check box value for autoscroll
function load_data(limit, start, search, tag){//recursive function for auto loading
    search = $('#search').val();
    var loads;
    $.ajax({
         url:"/modules/posts/questions_all_autoscroll_fetchdata.php",
         method:"POST",
         data:{limit:limit, start:start, search:search, tag:tag},
         cache:false,
         success:function(data){
            $('#load_data_message').show();//bring loading button back once load successful.  
            //It is removed during tag click search to avoid glitchy appearance of button showing at top left briefly.
            $('#load_data').append(data);
            //checks if quantity "limit" amount loaded.  If not, that means end of data reached.
            //Each data piece has id="container", so counting them tells how many data pieces returned in "loads"
            loads = $(data).find('.card-header').length;             
            if(loads<limit){button_name = 'End of Data';}else{button_name='Loading More &nbsp;&nbsp;<i class="fas fa-spinner fa-lg fa-spin"></i>';}
            if(autoscroll == 'false'){button_name = 'Load More'};
            //append data returned to bottom of existing data
            $('#load_data_message').html("<div id='please_wait' class='form-row text-center'>\
                  <div class='col-12'><button type='button' class='btn btn-warning'>\
                  "+button_name+"</button>\
                  <label style='cursor:pointer;'><input id='autoscroll' type='checkbox' name='autoscroll' value='true' "+checked+"\
                  style='transform:scale(2.0);margin-left:10px;margin-top:15px;cursor:pointer;'>&nbsp;&nbsp;Autoscroll</label><br></div></div>");
            action = "inactive";
            //recursive part - keep loading data until bottom of screen reached, stop when reached, or when end of data
            start = start + limit;
            console.log(start);
            if(loads>=limit){
                if($("#load_data").height() < $(window).height()){load_data(limit,start,search,tag);}
            }
        }
    });            
}

我在页面加载时对列表进行初始加载:

//for initial loading of data to the bottom of page (through recursive load_data function
if(action == 'inactive') {
    action = 'active';
    load_data(limit, start,search, tag);
 }  

然后,如果我想启动自动/无限滚动,我单击启动下面代码的复选框。但是,“start”值是“0”,它之前应该受到 Ajax 递归函数的影响,而是从“15”开始。我重复了以前发布的数据,这是不想要的。

//auto scroll checkbox clicked, putting into autoload/autoscroll mode
$(document).on("change", "#autoscroll", function(){
    autoscroll = this.checked;
    if(autoscroll == true){checked = 'checked';}else{checked = '';}
    console.log(start);
    load_data(limit, start, search, tag);
});

然后自动/无限滚动的工作方式如下。 "start" 变量不断更新成功,但可能在循环内,而不是递归 Ajax 部分。

//autoload portion.  when scrolling reaches bottom of screen, triggers another load of data      
$(window).scroll(function(){
    if(autoscroll == true){
        if($(window).scrollTop() + $(window).height() > $("#load_data").height() && action == 'inactive' && button_name != 'End of Data'){  
            action = 'active';
            start = start + limit;
            //load_data(limit, start, search, tag);
            setTimeout(function(){
             load_data(limit, start, search, tag);
            }, 500);
            console.log('scroll function called!');
        }
    }
});

底线问题 - 我想使用全局变量“start”并通过递归函数的 Ajax 成功函数对其进行更改。如何实现?

【问题讨论】:

    标签: javascript jquery ajax global-variables


    【解决方案1】:

    您还没有提到您的 ajax 调用中的“数据”响应是什么样的。 我尝试了一个如下所示的响应字符串:

    <div class='card-header'>hello</div>
    <div class='card-header'>world</div>
    <div class='card-header'>foo</div>
    <div class='card-header'>bar</div>
    <div class='card-header'>howdy</div>
    

    在这种情况下,loads = $(data).find('.card-header').length 不提供 5 的长度。如果 loads 是只有您在特定的 ajax 调用中加载的内容,然后您才需要 $(data).length。然后,ajax 调用中 start 的控制台日志会增加。

    注意:Jquery $.find 在 DOM 树上工作。 $(data) 返回单个节点的数组,$(data).length 将返回返回的数据。

    【讨论】:

    • 你说的那段代码不起作用似乎对我有用。它确实计算了'card-header'类的数量,这=从数据库中获取的项目数,这反过来= 5,除非它已经到达数据的末尾,然后小于5并更改按钮消息。如果有兴趣,您可以查看我对上面问题的回答(刚刚发布)。
    【解决方案2】:

    “loads = $(data).find('.card-header').length” 确实计算了 class='card-header' 实例的数量,这与 user2137480 上面提到的相反,并且一切都在增加适当地。问题是 Ajax 成功函数之外的“start”变量没有被更新,因为“load_data”函数被递归调用。

    找到了一种笨拙的方法来完成这项工作。我使用了一个会话存储变量“sessionStorage.start”,它会在 Ajax 成功函数中受到影响,即使在递归级别也是如此。似乎会话变量范围是真正的“全局”!然后这个 sessionStorage.start 变量在代码中的其他地方使用来更新全局“start”变量。然后在整个代码中始终保持此值。只需要记住会话变量是文本并且必须转换为数字(无论如何对于这个应用程序)。有兴趣的请看下面:

    //****************************************************************
    //        Loading questions and answers listings
    //****************************************************************
    var limit = 5;//number of records to autoload each time
    sessionStorage.start = 0;
    var start = 0;//start at record 0
    sessionStorage.start = start;
    sessionStorage.scroll_function_enable = 'false';
    var action = 'inactive';//initial status to get initial load
    var autoscroll = 'false';//check box to engage auto scroll or keep manual load more 
    var checked = '';//check box value for autoscroll
    function load_data(limit, start, search, tag){//recursive function for auto loading
        console.log('load data begin');
        console.log('recursive start: ' + start);
        sessionStorage.scroll_function_enable = 'false';
        search = $('#search').val();            
        var loads;
        $.ajax({
             url:"/modules/posts/questions_all_autoscroll_fetchdata.php",
             method:"POST",
             data:{limit:limit, start:start, search:search, tag:tag},
             cache:false,
             success:function(data){
                $('#load_data_message').show();//bring loading button back once load successful.  
                //It is removed during tag click search to avoid glitchy appearance of button showing at top left briefly.
                $('#load_data').append(data);
                //checks if quantity "limit" amount loaded.  If not, that means end of data reached.
                //Each data piece has id="container", so counting them tells how many data pieces returned in "loads"
                loads = $(data).find('.card-header').length;   
                //alert(loads);
                if(loads<limit){button_name = 'End of Data';}else{button_name='Loading More &nbsp;&nbsp;<i class="fas fa-spinner fa-lg fa-spin"></i>';}
                if(autoscroll == 'false'){button_name = 'Load More'};
                //append data returned to bottom of existing data
                $('#load_data_message').html("<div id='please_wait' class='form-row text-center'>\
                      <div class='col-12'><button id='load_button' type='button' class='btn btn-warning'>\
                      "+button_name+"</button>\
                      <label style='cursor:pointer;'><input id='autoscroll' type='checkbox' name='autoscroll' value='true' "+checked+"\
                      style='transform:scale(2.0);margin-left:10px;margin-top:15px;cursor:pointer;'>&nbsp;&nbsp;Autoscroll</label><br></div></div>");
                action = "inactive";
                //recursive part - keep loading data until bottom of screen reached, stop when reached, or when end of data                    
                start = start + limit;
                sessionStorage.start = start;//needed because recursive routine does not update the global "start" variable.  Needed to pass value outside of recursive routine
                console.log('recursive end: '+start);
                if(loads>=limit){
                    if($("#load_data").height() < $(window).height())
                    {
                        load_data(limit,start,search,tag);
                    }else
                        sessionStorage.scroll_function_enable = 'true';
                    }
            }
        });  
    
    }
    //for initial loading of data to the bottom of page (through recursive load_data function
    if(action == 'inactive') {
        action = 'active';
        load_data(limit, start,search, tag);
        start = Number(sessionStorage.start);//to get recursive value of start, otherwise will not retain its value
     }  
    
    //auto scroll checkbox clicked, putting into autoload/autoscroll mode
    $(document).on("change", "#autoscroll", function(){
        autoscroll = this.checked;
        if(autoscroll == true){checked = 'checked';}else{checked = '';}
        start = Number(sessionStorage.start);//to get recursive value of start, otherwise will not retain its value            
        console.log('autoscroll start: ' + start);
        load_data(limit, start, search, tag);
        start = Number(sessionStorage.start);//to get recursive value of start, otherwise will not retain its value
    });    
    
    //autoload portion.  when scrolling reaches bottom of screen, triggers another load of data      
    
    $(window).scroll(function(){
        if(autoscroll == true){
            if($(window).scrollTop() + $(window).height() > $("#load_data").height() && action == 'inactive' && button_name != 'End of Data' && sessionStorage.scroll_function_enable == 'true'){  
                action = 'active';
                start = Number(sessionStorage.start);//to get number where other processes have left off
                console.log('scroll start: ' + start);
                //load_data(limit, start, search, tag);
                setTimeout(function(){
                 load_data(limit, start, search, tag);
                }, 500);
                start = Number(sessionStorage.start);//to get recursive value of start, otherwise will not retain its value
            }
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多