2009-05-27 1 views
27

は、document.getElementsByTagNameの2回の呼び出しで返された2つのNodeListsを結合する方法ですか?JavaScript NodeList

言って、私は結果をループにしたい次のコード

var inputs = documentElement.getElementsByTagName('input'); 
var selects = document.getElementsByTagName('select'); 

を持っています。 1つのループで可能ですか?

ありがとうございます!

+0

これらを同時にまたは順次ループしていますか? –

答えて

46

は思えます。 (See here

var inputs = document.getElementsByTagName('input'); 
var selects = document.getElementsByTagName('select'); 

inputs = Array.prototype.slice.call(inputs); 
selects = Array.prototype.slice.call(selects); 

var res = inputs.concat(selects); 

alert(res.length); 
+1

私はちょうどそれを言っていた:) +1プロトタイプおよび他のライブラリはスライスを使ってノードリストを配列に変換します。 –

+10

これは、Internet ExplorerやBlackBerryのブラウザでは動作しないことに注意してください。 jQuery 1.4には興味深いテストがあり、ノードリストを結合するループにフォールバックするために使用されます。私はここでそれを抜粋しました:http://pastebin.com/TkTwMG17 –

4

NodeListタイプは、独自のオブジェクトを生成する必要がありますを意味し、(例えばthis articleを参照)不変です。

単純な方法は、配列を作成し、その配列にすべての要素をコピーすることです。

var inputs = documentElement.getElementsByTagName('input'); 
var selects = document.getElementsByTagName('select'); 
var all = new Array(inputs.length + selects.length); 

var index = 0; 
for (i = 0; i < inputs.length; i++) 
    all[index++] = inputs[i]; 
for (i = 0; i < selects.length; i++) 
    all[index++] = selects[i]; 

all変数には、2つのノードセットの和集合が含まれます。私は、ノードのコレクションと連結からの配列を作ったように、

Array.prototype.concat.call(selects, inputs); 

しかし、それは動作しません:

+0

とにかく2つのループが必要です。私の特定のタスクでは、結果をループする必要があるので、オブジェクトを作成する価値はありません。私は結果に参加することはできません、それは私が知りたかったことです、ありがとう! –

+0

ええ、2つのループを使用して私の意見では、最も明白な解決策は、とにかくです。 (私は1つのループオプションを考慮しましたが、実際には役に立たないです。)うれしい解決策があります。 – Noldorin

+1

まあ。 Array.prototype.slice.call(thatNodeListOfYours、0)はどうでしょうか? ? – Witiko

0

まず、私がこのようなArray.prototypeをを使用して配列を、CONCATすることが可能であることを考えましたそれ。そのように見える:

(function() { 

    var inputs = document.getElementsByTagName('input'), 
     selects = document.getElementsByTagName('select'), 
     result, 
     i, 
     node; 

    function convert (collection) { 
     var a = []; 
     for (var i = 0, length = collection.length; i < length; i++) { 
      a.push(collection[i]); 
     } 
     return a; 
    } 

    // concatenation && convertation 
    result = Array.prototype.concat(convert(inputs), convert(selects)); 
    // traversing 
    i = result.length; 
    while(node = result[--i]) { 
     alert(node.getAttribute('name')); 
    } 

})(); 
+0

私は最初のトリックがIEを除いて(主要な)ブラウザで動作すると信じています。 –

+0

そして、最初のトリックはWebKitベースのブラウザ(safari、chrome) –

20

あなたがそれらを結合することはできませんが、あなたはまだ順番で一つのループこのようにそれらをループすることができます:jQueryのを使用して代わりに

for (var i = 0; i < inputs.length + selects.length; i++) { 
    var element = (i < inputs.length) ? inputs[i] : selects[i-inputs.length]; 
} 

は、あなたがそれらすべてを選択することができます一回:あなたはargs配列のようなオブジェクトが配列になって作る同じArray.prototype.slice.callを使用することができるように

$('input, select') 
+0

+1では両方のオプションを提供していて、エレガントなforループでは機能しません。 – annakata

+0

+1でjQueryオプションを指摘してください。 –

+0

ニース! thnaks :) –

12
document.querySelectorAll("input, select"); 
+2

は、FF 3.1以上、Safari 3.1以上、またはIE8 + – Dementic

1

私は一緒にこれを投げました。すべてのループでを実行すると少しのオーバーヘッドが発生する可能性がありますが、要素の数が極端に増えない限り、私はそのマイナーなものだと思いますが、.lengthです。ブックマークレット用

inputs = div.getElementsByTagName('input'); 
selects = div.getElementsByTagName('select'); 
for (i=0; i<inputs.length+selects.length; i++) { 
    element = (i<inputs.length ? inputs[i] : selects[i-inputs.length]); 

    // do whatever with element 
} 
+0

が必要です。上記のいくつかの投稿と同じです...それは見ませんでした。 –

1

私のショートコード:

var e, t = d.getElementsByTagName('textarea'), u = d.getElementsByTagName('input'), i = t.length; 
    while(e = (i > 0) ? t[--i] : u[-i--]){ if(e.offsetHeight > 0)... } 
2
function mergeNodeLists(a, b) { 
    var slice = Array.prototype.slice; 
    return slice.call(a).concat(slice.call(b)); 
} 

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

0

は今日では、私は間違いなく、次を使用します。

クロム、Firefox 3の。5+、IE8 +

var elements = document.querySelectorAll('a'); 

for (var i = 0, element; (element = elements[i]); i++) { 
    console.log(element); 
} 

let elements = document.querySelectorAll('a'); 

for (let i = 0, element; (element = elements[i]); i++) { 
    console.log(element); 
} 

"要素= [i]は要素" ので "elements.length" よりも好ましい(有効実験と)IE11 +、Firefoxの24+、クロム30+:

"ノードリストは、長さのようなプロパティを得ることはO(n)であり、長さをO(n^2)に再確認してリストを反復することを意味します。 "

私はO(1)を覚えている限り、配列アクセスとは異なります。

詳細:

0

Array.prototype.slice.call()はIE 7で失敗し、これを使用する:

Object.prototype.getMyElements = function(tags){ 
    tags = tags.split(','); 
    var i, j, col=[], ci=0; 
    for(i=0; i<tags.length; i++) { 
     var objs = this.getElementsByTagName(tags[i]); 
     for(j=0; j<objs.length; j++) col[ci++] = objs[j]; 
    } 
    return col; 
} 
var objs = document.getMyElements('INPUT,TEXTAREA'); 
var objs = document.getElementById('myform').getMyElements('INPUT,TEXTAREA'); 
0

を試してみてください、私のway:

var allES = []; 
var inputs = document.getElementsByTagName("input"); 
     for (i = 0; i < inputs.length; i++) { 
       allES.push(inputs[i]); 
      } 
    // gather SELECT elements 
     var selects = document.getElementsByTagName("select"); 
      for (i=0; i < selects.length; i++){ 
       allES.push(selects[i]); 
       } 
関連する問題