2010-03-12 89 views
17

我原本是要求一個優雅的方式來模擬getElementsByTagName函數在IE或老版本瀏覽器中的結果Array.concat()的功能,因爲它好像不支持concat。當然,這只是 - 返回的對象不支持它的原因是因爲它不是Array。哎呀!Javascript - 將多個NodeLists連接在一起

getElementsByTagName實際上返回NodeList。那麼真正的問題是:什麼是獲取文檔中所有表單元素(input,select,textarea,button)的單個列表的好方法來遍歷它們?一個數組不是必需的...單個NodeList也是完美的。

請注意,我正在使用IE6,因爲這是企業內部網(儘管IE8很快)。

,我想出的答案是:

  • 它變得更簡單,可能表現較好,只是把代碼放到一個單獨的函數,並把它稱爲三次不同的NodeLists,而不是擔心將它們合併爲一個好方法。

  • 我最終切換到使用MooTools的(讀了幾個小時的所有不同的框架的比較之後)。所以現在,獲得我想要的物品數組非常簡單。我建議使用這樣的JavaScript框架,而不是讓人們絞盡腦汁想出最好的方法來做事。當然,我真的都是在學習原始語言(這就是爲什麼我長時間使用框架的原因),但它並不總是最快的方式去實現事情,在一個企業中,這往往同樣重要作爲提高編碼員的語言能力。

更新:差不多2年後,我只會使用jQuery並完成它!

+2

IE支持這個,你能澄清一下這個問題嗎? – 2010-03-12 02:32:22

+0

使用jQuery絕對是最好的選擇。但是,在我沒有訪問jQuery的情況下,我遇到了這個問題。我最終創建了一個我想要執行的元素標記數組,並循環它,爲每個元素調用getElementsByTagName。我想知道這或多或少比頂級答案有效。 – bpscott 2013-03-28 17:56:06

+0

@bpscott但是你是否已經把所有的元素都放到了一個單一的數組中,或者一次只處理一個標籤的值? – ErikE 2013-03-28 17:58:15

回答

31

要連接節點列表,請使用Array.prototype.slice.call將它們轉換爲數組,然後將它們正常連接。

var a = Array.prototype.slice.call(document.getElementsByTagName("p")), 
    b = Array.prototype.slice.call(document.getElementsByTagName("div")) 

var c = a.concat(b); 

編輯:(響應您的評論)

如果只有幾個類型的元素,這是好的,但性能有所下降與DOM的數量叫你做。這可能是更好更快地做document.getElementsByTagName('*'),環通列表,並挑選所需nodeName的元素。

要記住的另一件事是上面使用的Array.prototype.slice方法可能不適用於所有瀏覽器。退房評論中sizzle.js(後面的jQuery選擇器引擎)

當然起跑線#723,最好是使用像jQuery庫,處理所有的頭痛。你可以簡單地做:

$("input, select, textarea, <other tags>") 
+0

我只是尋找一個簡單的方法來獲取多個元素的列表(在這種情況下,表單元素INPUT,SELECT,TEXTAREA,可能還有按鈕)。這是最好的方法嗎?我想是時候開個新問題了。 – ErikE 2010-03-12 03:14:35

+0

@Emtucifor:我已經更新了我的答案。 – 2010-03-12 03:29:28

+0

對於document.getElementsByTagName(「*」)調用需要引用,並且nodeName是要查找的內容。 – 2013-10-08 20:24:29

1
var a1=document.getElementsByTagName('div'), 
a2=document.getElementsByTagName('button'); 
a1=[].slice.call(a1, 0,a1.length).concat([].slice.call(a2, 0,a2.length)) 
3
function mergeNodeLists(a, b) { 
    var slice = Array.prototype.slice; 
    return slice.call(a).concat(slice.call(b)); 
} 

console.log(mergeNodeLists(inputs, selects)); // => [input, select]

+1

我真的沒有看到這會爲所選答案增加更多內容。不過謝謝您的參與! – ErikE 2013-06-24 01:30:27

0

我還以爲那裏會是更多的答案不是這個,反正我給這個一杆,並具有以下功能上來儘管我不得不把我的頭腦一點點。

function group_elements(element, tags) { 
    var elements = element.getElementsByTagName('*'); 
    var results = []; 
    for (var i = 0; i < elements.length; ++i) { 
     if (tags.indexOf(elements[i].nodeName.toLowerCase()) > -1) { 
     results.push(elements[i]); 
     } 
    } 
    return results; 
} 


var form = document.getElementById('form'); 
var tags = ['input', 'select']; 
console.log(group_elements(form, tags)); 
+0

問題:不要使用字符串,使用數組:'var nodes = ['input','select'];'那麼不需要分割。不要修改參數。重新聲明參數是無意義的。 'node'不是一個好名字,請嘗試'tagName'(它們是字符串,而不是節點對象)。 JavaScript慣用camelCase,所以'selected_elements'應該是'selectedElements'。 – ErikE 2016-03-27 15:16:11

1

隨着ES6 spread operator你可以做

let arr = [...nodeList1, ...nodeList2]; 
+0

我昨天才想到這個! – ErikE 2017-04-12 15:50:32