JavaScript NodeList

est-il un moyen de rejoindre 2 NodeLists retournés par 2 appels de document.getelemensbytagname?

dites, j'ai le code suivant

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

je veux faire le tour des résultats. Est-ce possible en une seule boucle?

Merci d'avance!

27
demandé sur kethinov 2009-05-27 13:17:25

11 réponses

Semble que vous pouvez utiliser le même Tableau.prototype.tranche.appel qui fait de l'objet args de type tableau un tableau. ( voir ici )

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);
46
répondu Simon 2017-05-23 12:22:53

vous ne pouvez pas les joindre, mais vous pouvez toujours les passer en boucle séquentiellement dans une boucle comme celle-ci:

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

alternativement, en utilisant jQuery, vous pouvez les sélectionner tous en une seule fois:

$('input, select')
20
répondu Mario Menger 2009-05-27 09:54:33
document.querySelectorAll("input, select"); 
12
répondu Yansky 2010-02-23 11:36:36

pour autant que je sache, le type NodeList est immuable (voir cet article par exemple), ce qui signifie que vous devrez générer votre propre objet.

une méthode simple serait juste de créer un tableau et copier tous les éléments dans ce tableau.

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];

la variable all contient alors l'union des deux ensembles de noeuds.

4
répondu Noldorin 2009-05-27 09:34:54
function mergeNodeLists(a, b) {
  var slice = Array.prototype.slice;
  return slice.call(a).concat(slice.call(b));
}

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

2
répondu yckart 2014-12-04 00:20:35

j'ai rassemblé ça. Il pourrait y avoir un peu de surcharge de faire un si et .longueur pour chaque boucle, mais je pense que sa mineure à moins que le nombre d'éléments deviennent extrêmes.

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
}
1
répondu Mike K. 2011-04-04 22:45:30

Mon code court pour favoris:

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)... }
1
répondu user1727984 2012-10-08 07:18:13

tout d'abord, j'ai pensé que c'est possible de concater des tableaux en utilisant des tableaux.prototype, comme ceci:

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

mais ça ne marche pas, donc j'ai fait des tableaux à partir de collections de noeuds et je les concatte. On dirait que:

(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
répondu Alexander Ulizko 2009-05-27 09:53:21

de nos jours, j'utiliserais certainement ce qui suit:

Chrome, Firefox 3.5+, IE8+

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

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

IE11+, Firefox 24+, Chrome 30+ (avec possibilité d'expériences)

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

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

"element = elements[i]" est préféré à "des éléments.longueur "depuis:

" les listes de noeuds sont souvent implémentées comme des itérateurs de noeuds avec un filtre. Cela signifie que l'obtention d'une propriété comme length est O(n), et itérer sur le liste par re-vérification de la longueur O(n^2)."

contrairement à array access, qui est aussi loin que je me souviens O(1).

plus de détails:

0
répondu Artur Beljajev 2014-02-17 01:55:16

tableau.prototype.tranche.call () échoue dans IE 7, Utilisez ceci:

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
répondu Martin Zvarík 2014-04-02 16:14:48

essayez à ma façon:

 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]);
                }
0
répondu Nadeem 2015-02-24 12:05:51