2014-11-14 58 views
0

使用jQuery處理導航菜單腳本。該腳本正在進行遞歸設計,因此對菜單所具有的層數沒有硬編碼限制。Javascript:遞歸,jQuery錯誤

我的代碼開始:

navigationMenu.prototype.reset = function (ulElement, colorIndex, colors) { //Color index should always be 1 when directly calling this function 
var listItems = $(ulElement.children); 
var numItems = listItems.length; 
var targetWidth = (100/numItems) + '%'; 

listItems.each(function (x) { 
    var children = $(listItems[x].children); 
    var xT = $(listItems[x]).prop('tagName'); 
    var subMenu = null; 

    children.each(function (y) { 
     var yT = $(children[y]).prop('tagName'); 

     if (yT == 'UL') { 
      subMenu = $(children[y]); 
     } else if (yT == 'A') { 
      $(children[y]).css('background-color', colors[colorIndex-1]); //Offset by 1 to facilitate for 0 indexed arrays 
      $(children[y]).hover(function() { //Set hover color to the opposite 
       $(children[y]).css('background-color',colors[(3-colorIndex)-1]); //3-1 = 2 and 3-2 = 1, subtract 1 to facilitate 0 indexed arrays 
      }, function() { 
       $(children[y]).css('background-color',colors[colorIndex-1]); //3-1 = 2 and 3-2 = 1, subtract 1 to facilitate 0 indexed arrays 
      }); //Rest of style SHOULD be handled by css (width 100%, text color, text align) 
     } 
    }); 

    if (subMenu !== null) { //Recurse 
     navigationMenu.prototype.reset(subMenu, (3 - colorIndex), colors); //Not defined? 
    } 

    if (xT == 'LI') { //Format the element 
     $(listItems[x]).css('width',targetWidth); 
     $(listItems[x]).css('background-color', colors[colorIndex]); 
    } 
}); 
}; 

下,該錯誤:

Uncaught TypeError: Cannot read property 'firstChild' of null <-whitespace-> jquery-1.11.1.min.js:2 

我關心的是,似乎是錯誤並不直接從我的代碼來,相反, jQuery庫中的一個函數;然而,我正在爲這件事情付出高昂的代價,那是因爲我做錯了事。

現場演示可以在這裏找到: http://proofoftheilluminati.com/test/test.html

有關菜單的最後一下,你可以看到懸停效果和簡單的JS腳本頂層的一個想法,數學的鏈路寬度在這裏: http://proofoftheilluminati.com/test/index.html

腳本: http://proofoftheilluminati.com/test/scripts/menu.js

我託管的jQuery的版本1.11.1新鮮下載的副本: http://proofoftheilluminati.com/test/scripts/jquery-1.11.1.min.js

應該做的事情: 頂級名單應該是橙色與黑色達效 第二級列表應該是黑色與橙色懸停效果 第三級列表應該是一樣的第一等

定位是由外部的css文件處理

它在做什麼: 正確處理頂級列表,似乎在樣式二級列表之前出錯。

如果我遺漏了任何東西,請讓我知道。我試圖徹底。

編輯:提供的代碼已經上線一個自稱評論:

//Not defined? 

這是從以前的錯誤遺留下來的,我遇到了麻煩得到它認識到遞歸函數調用。我嘗試了以下線在這裏,他們不會允許的功能進步:

this.reset(subMenu, (3 - colorIndex), colors); 
reset(subMenu, (3 - colorIndex), colors); 
navigationMenu.reset(subMenu, (3 - colorIndex), colors); 

此外,該函數被調用時,該文件已準備就緒:

$(document).ready(function() { 
    s = new navigationMenu('#NavMenu', '#884106', '#000000', -1); 
}); 

編輯:修改後的代碼使用X/y而不是索引和xT/yT而不是標籤(已刪除嵌套變量同名)

+0

避免使用相同的名稱對於嵌套變量 – 2014-11-14 19:29:14

+0

我覺得奇怪使用索引兩次。對於同一個想法,我也使用不同的名字感到奇怪。 – gNerb 2014-11-14 19:32:19

+0

但是你應該使用'this'而不是'listItems [index]'和'children [index]' – 2014-11-14 19:44:54

回答

1

當您第一次打電話給navigationMenu.prototype.reset時,我猜ulElement是一個DOM元素,但是當您遞歸調用它時, subMenu,這是一個jQuery對象。這將是以下行的一個問題:

var listItems = $(ulElement.children); 

嘗試更改下面的代碼行:

navigationMenu.prototype.reset(subMenu, (3 - colorIndex), colors); 

要:

navigationMenu.prototype.reset(subMenu[0], (3 - colorIndex), colors); 

我寧願永遠前綴變量引用帶有「$」的jQuery對象來保持它們平直。

您也可以在給.each()的函數中使用this。因此,而不是:

children.each(function(index) { 
    var tag = $(children[index]).prop('tagName'); 

你可以有:

children.each(function() { 
    var $child = $(this), 
     tag = $child.prop('tagName'); 

你也可以考慮在所有情況下使用jQuery .children()方法,而不是children DOM元素屬性

+0

有趣的反饋,你完全正確的區別,改變第一次出現到一個jQuery選擇立即導致問題,而不是等待第二次發生。至於關於「這個」的評論,我不喜歡那種方法,我的測試表明兩者之間沒有性能差異。 – gNerb 2014-11-14 19:55:12

+0

這就是爲什麼我問你們。你的修復工作完美。謝謝! – gNerb 2014-11-14 20:06:08