2013-07-08 62 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鏈接很有幫助。 –