Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/469.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript-递归-迭代json,用户可以跳过_Javascript_Jquery_Json_Recursion - Fatal编程技术网

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);
        }
    });
}