2013-07-08 69 views
1

我有一个小问题,从自身内部调用自己的函数。 下面的函数非常作品,在这里可以看到...jquery/javascript错误 - 太多的递归 - 与自我调用功能

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

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

}); 

回答

1

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

递归函数最适用于像扫描列表树那样的情况,在这种情况下,您不知道它们到底有多深。供参考,Code Academy有我觉得有用的递归部分。

+1

不能相信我没有想到这一点..非常感谢,你救了我很多挫折,我被困在离开事件处理程序的功能因为我以为我使用的信息特定于该功能(即数组),但现在看到它,我意识到我只使用过这个全球空间的数组。已经移除并放置在docready中的ajax调用之后,可以工作。案件关闭。实际上,今天早些时候我确实偶然发现了代码学院的一部分,它非常好,它让我意识到我正在用错误的方式使用递归,但我希望能够绕过它,再次感谢! – user1125489

+0

不错的帖子@IsaacSuttell。 Code Academy链接很有帮助。 –