我有一个递归函数,该函数会填充一个列表,直到到达屏幕底部,然后停止。
每次调用递归函数时,“开始”全局变量都会增加限制(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 <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;'> 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成功函数对其进行更改。如何实现?
答案 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 <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;'> 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
}
}
});