全局变量在 JQuery Ajax 成功函数中不受影响



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

每次调用递归函数时,"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 成功函数对其进行更改。 如何实现这一点?

你没有提到你的"数据"响应在你的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>

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

$(data) 返回单个节点的数组,$(data).length 将返回返回的数据片段。

"load = $(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
}
}
});

最新更新