2011-09-12 30 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元素可以是锚点,链接或两者)。