Javascript-递归-迭代json,用户可以跳过
我正在我的网站上实现一个趋势分析功能,我想知道在递归函数中处理用户点击事件的最佳方法 代码示例:Javascript-递归-迭代json,用户可以跳过,javascript,jquery,json,recursion,Javascript,Jquery,Json,Recursion,我正在我的网站上实现一个趋势分析功能,我想知道在递归函数中处理用户点击事件的最佳方法 代码示例: var trendingCodes = []; // trendingCodes is json populated by ajax, this part works fine and not included for brevity // looks like {code:'SadPanda', text:'Thanks for checking out my !shouttag', img
var trendingCodes = [];
// trendingCodes is json populated by ajax, this part works fine and not included for brevity
// looks like {code:'SadPanda', text:'Thanks for checking out my !shouttag', img:false}
// Kick this pig
showTrendingCode(0, 200);
function showTrendingCode(indexCurrent, fadeSpeed)
{
var indexNext = ((indexCurrent + 1) % trendingCodes.length);
var trendingCode = trendingCodes[indexCurrent];
if (trendingCodes.length > 1) {
// !!!! Problem
// I am trying to register an event handler for the 'next' trending code
// but if I click multiple times it causes a 'maximum stack exceeded' error
jQuery('#trending-refresh').off().on('click', function()
{
showTrendingCode(indexNext, 200);
});
jQuery('#trending-text p').add(jQuery('#trending-title span')).add(jQuery('#trending-refresh')).fadeIn(fadeSpeed);
setTimeout(function () { showTrendingCode(indexNext, 600); }, 5000);
}
}
正如您所看到的,我正在尝试为dom元素注册一个事件处理程序(下一步),但是如果用户多次单击该链接,就会出现“超出最大堆栈”错误。如果用户根本不点击,那么函数就可以正常运行(永久运行,这是理想的效果)
有什么建议使这项工作符合要求吗
这里是lefiddle:尝试创建一个变量来引用定义的超时,使用
.stop()
,clearTimeout()
,将.one()
替换为.on()
#趋势文本p,
#趋势标题跨度{
显示:无;
}
趋向:
我选择将迭代器函数与表示函数分开,而不是使用递归,因此最终结果如下所示:
jQuery.ajax({
beforeSend: function() {
$('#trending-text p').text('Loading...');
$('#trending-title span').text('Loading...');
},
datatype: 'json',
url: '<?php echo url_for('@ajaxTrending') ?>',
success: function(data) {
if (data.status == 'success') {
jQuery.each(data.content, function(code, message)
{
if (message.length >= <?php echo $messageLength ?>) {
message = message.slice(0, <?php echo $messageLength ?>) + '...';
}
trendingCodes.push({code:code, img:false, text:message});
});
}
else {
trendingCodes.push({code:false, img:false, text:false});
}
// This makes the initial call to the iterator function
setTimeout(function() { showTrendingCodes(); }, 500);
}
});
// Iterator function
function showTrendingCodes()
{
var counter = 1;
// Show first code via separate function
showTrendingCode(trendingCodes[0], 300);
if (trendingCodes.length > 1) {
setInterval(function()
{
showTrendingCode(trendingCodes[counter++], 300);
if (counter >= trendingCodes.length) {
counter = 0;
}
}, 3500);
}
};
function showTrendingCode(trendingCode, fadeSpeed)
{
var $moneyshot = jQuery('#trending-moneyshot');
var $refresh = jQuery('#trending-refresh');
var $title = jQuery('#trending-title span');
var $text = jQuery('#trending-text p');
$text.add($title).fadeOut(fadeSpeed, function()
{
if (trendingCode.code) {
$moneyshot.attr('href', '/!/' + trendingCode.code);
$text.text(trendingCode.text);
$title.html('<a href="/!/' + trendingCode.code + '">!' + trendingCode.code + '</a>');
$text.add($title).fadeIn(fadeSpeed);
} else {
$title.text('!SADPANDA');
$text.text('Nothing is trending right now...');
$text.add($title).fadeIn(fadeSpeed);
}
});
}
jQuery.ajax({
beforeSend:function(){
$(#趋势文本p')。文本('加载…');
$(“#趋势标题范围”).text('Loading…');
},
数据类型:“json”,
url:“”,
成功:功能(数据){
如果(data.status==“成功”){
jQuery.each(数据、内容、函数(代码、消息)
{
如果(message.length>=){
message=message.slice(0,)+'…';
}
推送({code:code,img:false,text:message});
});
}
否则{
推送({code:false,img:false,text:false});
}
//这将对迭代器函数进行初始调用
setTimeout(函数(){showTrendingCodes();},500);
}
});
//迭代器函数
函数showTrendingCodes()
{
var计数器=1;
//通过单独的函数显示第一个代码
显示趋势代码(趋势代码[0],300);
如果(trendingCodes.length>1){
setInterval(函数()
{
显示趋势代码(趋势代码[counter++],300);
如果(计数器>=trendingCodes.length){
计数器=0;
}
}, 3500);
}
};
功能显示趋势代码(趋势代码、fadeSpeed)
{
var$moneyshot=jQuery(“#趋势moneyshot”);
var$refresh=jQuery(“#趋势刷新”);
var$title=jQuery(“#趋势标题跨度”);
var$text=jQuery(“#趋势文本p”);
$text.add($title).fadeOut(fadeSpeed,function()
{
if(趋势代码.代码){
$moneyshot.attr('href','/!/'+trendingCode.code);
$text.text(趋势代码.text);
$title.html(“”);
$text.add($title.fadeIn(fadeSpeed);
}否则{
$title.text(“!SADPANDA”);
$text.text('目前没有任何趋势…');
$text.add($title.fadeIn(fadeSpeed);
}
});
}
此解决方案工作正常,不会导致OP中提到的错误。当您单击时,您将调用
showTrendingCode
两次,一次从单击调用,一次从设置超时调用,我认为这是问题的根源。如果发生单击,您可能应该在设置超时之前返回。您可以创建stacksnippet或JSFIDLE来演示吗?将尝试用fiddle更新的.on()
替换.one()
@里克特:有道理。(at)guest:我来试一试。我在你的小提琴上看到了这些变化,你能解释一下$(“*”).stop()调用在做什么吗?我想把点击的(per@RickT comment)作为第三个参数传递进来,然后检查是否为真,如果为真,则不进行第二次调用即可返回。$(“*”)。包含stop()
,以停止调用的当前正在进行的动画。fadeIn()
有意义。您的解决方案似乎修复了超出最大堆栈的问题,但如果我单击几次,然后停止并让其恢复正常,它会将最近的一次重复几次。“但是如果我单击几次,然后停止并让其恢复正常,它会将最近的一次重复几次。”不确定解释“重复最近的一次”正确地重复显示!FOOBAR
连续?正确。它将重复几次,然后返回正常旋转。
jQuery.ajax({
beforeSend: function() {
$('#trending-text p').text('Loading...');
$('#trending-title span').text('Loading...');
},
datatype: 'json',
url: '<?php echo url_for('@ajaxTrending') ?>',
success: function(data) {
if (data.status == 'success') {
jQuery.each(data.content, function(code, message)
{
if (message.length >= <?php echo $messageLength ?>) {
message = message.slice(0, <?php echo $messageLength ?>) + '...';
}
trendingCodes.push({code:code, img:false, text:message});
});
}
else {
trendingCodes.push({code:false, img:false, text:false});
}
// This makes the initial call to the iterator function
setTimeout(function() { showTrendingCodes(); }, 500);
}
});
// Iterator function
function showTrendingCodes()
{
var counter = 1;
// Show first code via separate function
showTrendingCode(trendingCodes[0], 300);
if (trendingCodes.length > 1) {
setInterval(function()
{
showTrendingCode(trendingCodes[counter++], 300);
if (counter >= trendingCodes.length) {
counter = 0;
}
}, 3500);
}
};
function showTrendingCode(trendingCode, fadeSpeed)
{
var $moneyshot = jQuery('#trending-moneyshot');
var $refresh = jQuery('#trending-refresh');
var $title = jQuery('#trending-title span');
var $text = jQuery('#trending-text p');
$text.add($title).fadeOut(fadeSpeed, function()
{
if (trendingCode.code) {
$moneyshot.attr('href', '/!/' + trendingCode.code);
$text.text(trendingCode.text);
$title.html('<a href="/!/' + trendingCode.code + '">!' + trendingCode.code + '</a>');
$text.add($title).fadeIn(fadeSpeed);
} else {
$title.text('!SADPANDA');
$text.text('Nothing is trending right now...');
$text.add($title).fadeIn(fadeSpeed);
}
});
}