2011-09-12 84 views
0

我需要選擇兩個不同導航面板中的所有錨點元素。最好的方法是什麼?有效的& /或有效的。選項1:我可以設置每個導航到一個類,尋找類,抓住每個div中的所有錨與該類。Javascript:來自兩個Div ID的元素

選項2:我可以用一個ID設置每個導航。出於某種原因,我無法從每個div id中將兩個錨點數組連接起來。任何想法爲什麼,他們是陣列?防爆。

<code> 
var nav = document.getElementById("nav").getElementsByTagName("a"); 
var subnav = document.getElementById("subnav").getElementsByTagName("a"); 

var allnav = nav.concat(subnav); // Didn't seem to work 

// neither did this. Just seemed to break.  
for(var i=0;i<subnav.length;i++){ 
    nav.push(subnav[i]); 
} 
</code> 

選項3:通過ID獲取每個div。發送函數以循環,獲取錨點並執行適當的操作。

哪個會更快或使用更少的資源,& /或您認爲哪個更易於維護?

我知道jQuery有一個很好的方法,但由於我的代碼片段很短,我不希望只爲一些小函數添加整個庫。

謝謝你的幫助!

回答

0

getElementsByTagName返回NodeList。 A NodeList不是Array。然而

NodeList是陣列等,並且可以被轉換爲使用toArray

var toArray = function _toArray(obj) { 
    var arr = []; 
    for (var i = 0, ii = obj.length; i < ii; i++) { 
      arr.push(obj[i]); 
    } 
    return arr; 
}; 

var allnav = toArray(nav).concat(subnav); 

陣列或者您可以使用Array.prototype.slice.call(nav)NodeList轉換爲Array

您也可以將類anchor-nav添加到兩個導航欄,然後使用querySelectorAll

var anchors = document.querySelectorAll("nav.anchor-nav a");

+0

不要將本機對象當作本地對象,並且不要使用* for..in *,因爲NodeLists已命名不適合複製到Array的屬性(如* item *方法)。迭代使用for循環和計數器。 – RobG

+0

這就是我所見過的將NodeList轉換爲Array的最奇怪的方式。實際上,我敢肯定它不會工作,但是如果將'var arr = [];'更改爲'var arr = Array(obj.length);'... –

+0

@ alpha123爲什麼會這樣工作? – Raynos

0
var slice = document.body instanceof Object ? // IE < 9 has some really weird issues 
    Array.prototype.slice : function() { 
     for (var array = [], i = 0, l = this.length; i < l; ++i) 
      array[i] = this[i]; 
    }; 

var nav = slice.call(document.getElementById("nav").getElementsByTagName("a")); 
var subnav = slice.call(document.getElementById("subnav").getElementsByTagName("a")); 

var allnav = nav.concat(subnav); // Will work now. 

getElementsByTagName不返回陣列,它返回一個節點列表,其不具有concat方法。東西slice.call東西轉換成一個真正的數組。另外,它是更有效地做

nav.push.apply(nav, subnav); 
// nav is now the equivalent of allnav 
+0

'nav.push.apply(nav,subnav)' – Raynos

+0

上面的失敗在IE < 9. – RobG

+0

嘿,我一直在開車投票!!喔!哼!!我現在真的被拽到了Stackoverflow的arsehats大廳裏。是的!誰都沒有膽量說他們是誰,所以我認爲不回覆恭維。 – RobG

1

你接近:

var allnav = []; // initialise allnav as an array 

// Store length of NodeList, slight performance boost in some browsers 
// and is just neater 
for (var i=0, iLen=subnav.length; i<iLen; i++) { 
    allnav.push(subnav[i]); 

    // or 

    allnav[i] = subnav[i]; 
} 

不要使用Array.prototype.slice.call(),因爲你不應該像對待本地ECMAScript的對象,例如主機對象它將在IE <中失敗9.在任何地方都沒有規定主機對象必須像本地ECMA-262對象那樣行事(並且ECMA-262明確表示他們不需要)。

請注意,還有一個document.anchors集合和一個document.links集合(它們不是互斥的,A元素可以是錨點,鏈接或兩者)。

相關問題