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!
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);
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')
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.
function mergeNodeLists(a, b) {
var slice = Array.prototype.slice;
return slice.call(a).concat(slice.call(b));
}
console.log( mergeNodeLists( inputs, selects ) ); // => [input, select]
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
}
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)... }
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'));
}
})();
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:
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');
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]);
}