全局变量不受JQuery Ajax成功功能的影响

时间:2019-07-16 01:29:15

标签: javascript jquery ajax global-variables

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

每次调用递归函数时,“开始”全局变量都会增加限制(5)。例如,在3次之后,“开始”变量应为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);
 }  

然后,如果要启动自动/无限滚动,请单击复选框以启动下面的代码。但是,“开始”值是“ 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成功函数对其进行更改。如何实现?

2 个答案:

答案 0 :(得分:0)

您没有在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将返回返回的数据。

答案 1 :(得分:0)

“ loads = $(data).find('。card-header')。length”确实计算了class ='card-header'实例的数量,这与user2137480上面提到的情况相反,并且一切都会增加正确地。问题在于,由于递归调用了“ load_data”函数,因此未更新Ajax成功函数之外的“开始”变量。

找到一种笨拙的方法来完成这项工作。我使用了一个会话存储变量“ 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
        }
    }
});