jquery / javascript错误 - 太多的递归 - 具有自我调用功能 [英] jquery/javascript error - too much recursion - with self-calling function

查看:96
本文介绍了jquery / javascript错误 - 太多的递归 - 具有自我调用功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个从自身内部调用自身的函数的小问题。
以下函数相当有用,可以在这里看到...



http://jsfiddle.net/justinayles/frPZ8/2/



但是如果你点击一个正方形之后,点击后退链接并前后几次,最终会减速并最终因'递归错误太多'而崩溃。我真的不知道有什么其他方法可以实现我在这里要做的事情吗?我有点理解问题是什么,但想知道是否有另一种方法来做到这一点,也许重命名的功能?即时尝试避免重复太多的代码。任何帮助赞赏,谢谢。

  var questionArray = []; 
var cardArray = [];

//为IE扩展数组!
if(!Array.prototype.filter){
Array.prototype.filter = function(fun / *,thisp * /){
var len = this.length>>> ; 0;
if(typeof fun!=function)
throw new TypeError();

var res = [];
var thisp = arguments [1];
for(var i = 0; i< len; i ++){
if(i in this){
var val = this [i]; (fun.call(thisp,val,i,this))
res.push(val); //如果有趣的话改变这个
if
}
}
return res;
};
}

函数setupPage(whichpage,questionArray){

var html =,
backlink =,
activestep = ,
undertext =,
qArray = questionArray;

switch(whichpage){
case'1':

var pg1 = questionArray.filter(function(el){
return el.page ==step1;
});

$ .each(pg1,function(key,val){
html + ='< a class =quest'+ val.star +'href ='+ val .path +'target ='+ val.target +'>'+ val.title +'< / a>';
});

backlink =0;
activestep =1;
undertext =;

break;
case'2a':

var pg2a = questionArray.filter(function(el){
return el.page ==step2a;
});

$ .each(pg2a,function(key,val){
html + ='< a class =quest'+ val.star +'href ='+ val .path +'target ='+ val.target +'>'+ val.title +'< / a>';
});

backlink =1;
activestep =2;
undertext =;

break;
case'2b':

var pg2b = questionArray.filter(function(el){
return el.page ==step2b;
});

$ .each(pg2b,function(key,val){
html + ='< a class =quest'+ val.star +'href ='+ val .path +'target ='+ val.target +'>'+ val.title +'< / a>';
});

backlink =1;
activestep =2;
undertext =;

break;
case'3a':

var pg3a = cardArray.filter(function(el){
return el.page ==3a;
});

$ .each(pg3a,function(key,val){
html + ='< div class =cardblock>< a class =wrapcardhref = '+ val.path +'target ='+ val.target +'>< img border =0alt ='+ val.title +'src =http://dummyimage.com /178x112/000/00ffd5.pngalt =占位符图片/>< / a>';
html + ='< a class =cardtitlehref ='+ val.path + 'target ='+ val.target +'>'+ val.title +'< / a>< / div>';
});

backlink =2a;
activestep =3;
undertext =选择一个程序;

break;
case'3b':

var pg3b = cardArray.filter(function(el){
return el.page ==3b;
});

$ .each(pg3b,function(key,val){
html + ='< div class =cardblock>< a class =wrapcardhref = '+ val.path +'target ='+ val.target +'>< img border =0alt ='+ val.title +'src =http://dummyimage.com /178x112/000/00ffd5.png/>< / a>';
html + ='< a class =cardtitlehref ='+ val.path +'target =' + val.target +'>'+ val.title +'< / a>< / div>';
});

backlink =2b;
activestep =3;
undertext =选择一个程序;

break;
}

//让dom更改..
if(backlink!==0){
html + ='< a id = backlinkhref ='+ backlink +'>& lt;& lt;返回步骤< / a>';
}

$('。wrapdots span')。removeClass('active');
$('。wrapdots span.step'+ activestep).addClass('active');

$('p.underdots')。html(undertext);
$ b $('#wrapper')。fadeOut('fast',function(){
$(this).html(html).fadeIn('fast');
}); $('#wrapper')。on('click','#backlink',function(e){

e = e || window.event;
e.target = e.target || e.srcElement;

var goto = e.target.href;
goto = goto.split('/');
goto = goto.pop();

switch(goto){
case'1':
e.preventDefault();
setupPage('1' ,
case break';
case'2a':
e.preventDefault();
setupPage('2a',qArray);
break;
case'2b':
e.preventDefault();
setupPage('2b',qArray);
break;
case'3a':
e .preventDefault();
setupPage('3a',qArray);
break;
case'3b':
e.preventDefault();
setupPage('3b',qArray);
休息;
}

}); $('#wrapper')。on('click','.quest',function(e){

e = e || window.event;
e.target = e.target || e.srcElement;

var goto = e.target.href;
goto = goto.split('/');
goto = goto.pop();

switch(goto){
case'1':
e.preventDefault();
setupPage('1' ,
case break';
case'2a':
e.preventDefault();
setupPage('2a',qArray);
break;
case'2b':
e.preventDefault();
setupPage('2b',qArray);
break;
case'3a':
e .preventDefault();
setupPage('3a',qArray);
break;
case'3b':
e.preventDefault();
setupPage('3b',qArray);
休息;
默认值:
e.preventDefault();
休息;
}

});



// doc ready ...
$(function(){

//做问题
$('question')。each(function(){
var qobj = {
title:$(this).attr('qTitle'),
star:$(this)。 attr('class'),
path:$(this).attr('path'),
page:$(this).attr('page'),
target:$ (this).attr('target')
}
questionArray.push(qobj);
});

//有问题,现在让我们设置第1页!!
setupPage('1',questionArray);

// do cards
$('card')。each(function(){
var cobj = {
title:$(this).attr('cTitle'),
path:$(this).attr('path'),
img:$(this) .attr('img'),
page:$(this).attr('page'),
target: $(this).attr('target')
}
cardArray.push(cobj);
});

});


解决方案

这不是您想要的情况使用递归。每次点击都会将更多事件绑定到DOM,但不会释放它们。我建议将你的 $('#wrapper')。on('click'... code从你的 setupPage

递归函数最适用于像扫描列表树那样的情况,在这些列表树中你不知道它们会走多远。仅供参考, Code Academy 有关于递归的部分,我发现它很有帮助。


I have a small problem with a function that calls itself from within itself. The following function pretty much works, as can be seen here ...

http://jsfiddle.net/justinayles/frPZ8/2/

but if you click a square and after that click the back link and go back and forth a few times, eventually it will slow down and ultimately crash with a 'too much recursion error'. I cant really see any other way to achieve what I am trying to do here ? I kind of understand what the problem is, but was wondering if there was another way to do this, maybe rename the function? im trying to avoid duplication too much code. any help appreciated, thanks.

var questionArray = [];         
var cardArray = [];

// extend array for IE !!
if (!Array.prototype.filter) {
    Array.prototype.filter = function(fun /*, thisp*/) {
        var len = this.length >>> 0;
        if (typeof fun != "function")
            throw new TypeError();

        var res = [];
        var thisp = arguments[1];
        for (var i = 0; i < len; i++) {
            if (i in this) {
                var val = this[i]; // in case fun mutates this
                if (fun.call(thisp, val, i, this))
                    res.push(val);
            }
        }
        return res;
    };
}

function setupPage(whichpage, questionArray) {

    var html = "",
        backlink = "",
        activestep = "",
        undertext = "",
        qArray = questionArray;

    switch(whichpage) {
        case '1':

            var pg1 = questionArray.filter(function (el) {
                return el.page == "step1";
            });

            $.each(pg1, function(key,val) {
                html += '<a class="quest ' + val.star + '" href="' + val.path + '" target="' + val.target + '">' + val.title + '</a>';
            }); 

            backlink = "0"; 
            activestep = "1";
            undertext = "";

            break;              
        case '2a':

            var pg2a = questionArray.filter(function (el) {
                return el.page == "step2a";
            });

            $.each(pg2a, function(key,val) {
                html += '<a class="quest ' + val.star + '" href="' + val.path + '" target="' + val.target + '">' + val.title + '</a>';
            }); 

            backlink = "1";
            activestep = "2";
            undertext = "";

            break;
        case '2b':

            var pg2b = questionArray.filter(function (el) {
                return el.page == "step2b";
            }); 

            $.each(pg2b, function(key,val) {
                html += '<a class="quest ' + val.star + '" href="' + val.path + '" target="' + val.target + '">' + val.title + '</a>';
            }); 

            backlink = "1";
            activestep = "2";
            undertext = "";

            break;
        case '3a':

            var pg3a = cardArray.filter(function (el) {
                return el.page == "3a";
            });

            $.each(pg3a, function(key,val) {
                html += '<div class="cardblock"><a class="wrapcard" href="' + val.path + '" target="' + val.target + '"><img border="0" alt="' + val.title + '" src="http://dummyimage.com/178x112/000/00ffd5.png"  alt="placeholder image" /></a>';
                html += '<a class="cardtitle" href="' + val.path + '" target="' + val.target + '">' + val.title + '</a></div>';
            }); 

            backlink = "2a";
            activestep = "3";
            undertext = "Choose a programme";

            break;
        case '3b':

            var pg3b = cardArray.filter(function (el) {
                return el.page == "3b";
            }); 

            $.each(pg3b, function(key,val) {
                html += '<div class="cardblock"><a class="wrapcard" href="' + val.path + '" target="' + val.target + '"><img border="0" alt="' + val.title + '" src="http://dummyimage.com/178x112/000/00ffd5.png" /></a>';
                html += '<a class="cardtitle" href="' + val.path + '" target="' + val.target + '">' + val.title + '</a></div>';
            }); 

            backlink = "2b";
            activestep = "3";
            undertext = "Choose a programme";

            break;                  
    }

    // make the dom changes..
    if ( backlink !== "0" ) {
        html += '<a id="backlink" href="' + backlink + '">&lt;&lt; back a step</a>';
    }

    $('.wrapdots span').removeClass('active');
    $('.wrapdots span.step'+activestep).addClass('active');

    $('p.underdots').html(undertext);

    $('#wrapper').fadeOut('fast', function() {
        $(this).html(html).fadeIn('fast');
    });

    $('#wrapper').on('click', '#backlink', function(e) {

        e = e || window.event;
        e.target = e.target || e.srcElement;

        var goto = e.target.href;
        goto = goto.split('/');
        goto = goto.pop();

        switch(goto) {
            case '1':
                e.preventDefault(); 
                setupPage('1', qArray);
                break;
            case '2a':
                e.preventDefault(); 
                setupPage('2a', qArray);
                break;
            case '2b':
                e.preventDefault(); 
                setupPage('2b', qArray);                        
                break;
            case '3a':
                e.preventDefault(); 
                setupPage('3a', qArray);
                break;
            case '3b':
                e.preventDefault(); 
                setupPage('3b', qArray);                        
                break;                      
        }

    });

    $('#wrapper').on('click', '.quest', function(e) {

        e = e || window.event;
        e.target = e.target || e.srcElement;

        var goto = e.target.href;
        goto = goto.split('/');
        goto = goto.pop();

        switch(goto) {
            case '1':
                e.preventDefault(); 
                setupPage('1', qArray);
                break;
            case '2a':
                e.preventDefault(); 
                setupPage('2a', qArray);
                break;
            case '2b':
                e.preventDefault(); 
                setupPage('2b', qArray);                        
                break;
            case '3a':
                e.preventDefault(); 
                setupPage('3a', qArray);
                break;
            case '3b':
                e.preventDefault(); 
                setupPage('3b', qArray);                        
                break;  
            default:
                e.preventDefault(); 
                break;
        }

    });

}

// doc ready...
$(function() {

    // do questions
    $('question').each(function() {
        var qobj = { 
            title : $(this).attr('qTitle'),
            star : $(this).attr('class'),
            path : $(this).attr('path'),
            page : $(this).attr('page'),                            
            target : $(this).attr('target')
        }
        questionArray.push(qobj);
    });

    // got the questions, lets now setup page 1 !!
    setupPage('1', questionArray);

    // do cards
    $('card').each(function() {
        var cobj = { 
            title : $(this).attr('cTitle'),
            path : $(this).attr('path'),
            img : $(this).attr('img'),                              
            page : $(this).attr('page'),                            
            target : $(this).attr('target')
        }
        cardArray.push(cobj);                           
    });     

});

解决方案

This isn't a case you'd want to use recursion. Every click binds more events to the DOM but never releases them. I'd recommend pulling your $('#wrapper').on('click'... code out of your setupPage function that way your click events are only bound once.

Recursive functions are best used for situations like scanning list trees where you don't know how deep they go. FYI, Code Academy has section on recursion that I found helpful.

这篇关于jquery / javascript错误 - 太多的递归 - 具有自我调用功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆