我对一个从内部调用自身的函数有一个小问题。 以下功能非常有用,可以在这里看到......
http://jsfiddle.net/justinayles/frPZ8/2/
但是如果你点击一个正方形,然后点击后面的链接并来回几次,最终它会减速并最终因“过多的递归错误”而崩溃。我真的没有看到任何其他方式来实现我在这里尝试做的事情?我有点明白问题是什么,但是想知道是否还有其他方法可以做到这一点,也许重命名这个功能?我试图避免重复太多的代码。任何帮助表示感谢,谢谢。
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 + '"><< 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);
});
});
答案 0 :(得分:1)
这不是您想要使用递归的情况。每次点击都会将更多事件绑定到DOM,但永远不会释放它们。我建议您将$('#wrapper').on('click'...
代码从setupPage
功能中提取出来,使您的点击事件仅绑定一次。
递归函数最适用于扫描列表树的情况,在这种情况下,您不知道它们的深度。仅供参考,Code Academy有关于递归的部分,我发现它很有帮助。