2011-05-26 10 views
11

Por lo que entiendo, un option elementos que se originan select elementos en HTML son una matriz.
Así que, básicamente, lo que quiero hacer es devolver una cadena de matriz que está separada por comas.Javascript selecbox.options para array?

intenté hacer selecbox.options.join(',');, pero me dieron un error que no es compatible; ¿alguien tiene una idea de por qué?

+2

Desea devolver una matriz de elementos convertidos en una cadena, separados por comas; esto no tiene sentido. Básicamente será '[object HTMLOptionElement], [object HTMLOptionElement]' ¿quiere decir que quiere que los valores de cada opción estén separados por comas, o convertir un objeto similar a una matriz en una matriz simple? –

Respuesta

11

No es una matriz. Es un objeto Es "array-like"

de http://api.jquery.com/jQuery.each/ que puede iterar sobre cualquiera de los dos:

iterar sobre ambos objetos y arrays. Las matrices y los objetos similares a una matriz con una propiedad de longitud (como el objeto de argumentos de una función) se iteran mediante el índice numérico , de 0 a longitud-1. Otros objetos se iteran a través de sus propiedades con nombre .

Cada HTML Option element tiene un valor y un texto y algunos más atributos.

Un simple bucle for puede usarse

vals = [] 
var sel = document.querySelector("select"); 
for (var i=0, n=sel.options.length;i<n;i++) { // looping over the options 
    if (sel.options[i].value) vals.push(sel.options[i].value); 
} 

la Array.apply Publicado por typeracer va a devolver una matriz de HTMLOptionElements que aún debe ser puesto en loop o asignada para llegar a los valores y los textos

Aquí hay 3 versiones que devolverán lo mismo.

var vals, sel = document.querySelector("select"), show=function(vals) {$("#result").append("[" + vals.join("][") + "]<hr/>");} 
 

 
// jQuery mapping jQuery objects - note the "this" and the .get() 
 
vals = $('select > option').map(function() {return this.value;}).get(); 
 
show(vals); 
 

 
// plain JS using loop over select options 
 
vals = []; 
 
for (var i = 0, n = sel.options.length; i < n; i++) { // looping over the options 
 
    if (sel.options[i].value) vals.push(sel.options[i].value); // a bit of testing never hurts 
 
} 
 
show(vals); 
 

 

 
// Plain JS using map of HTMLOptionElements - note the el 
 
vals = Array.apply(null, sel.options).map(function(el) { return el.value; }); 
 
show(vals);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
 
<select> 
 
<option value="Please select">Text 0</option> 
 
<option value="one">Text 1</option> 
 
<option value="two">Text 2</option> 
 
<option value="three">Text 3</option> 
 
</select> The above select has the following option values:<br/> 
 
<span id="result"></span>

+0

por lo que sé que es una matriz de opciones (de lo contrario, ¿cómo podemos acceder a los elementos por índice? Como selectbox.options [1]?) lo que necesito para tomar todos los valores (no solo los valores seleccionados), conectarlos con comas y devuelve el resultado. – Dementic

+0

"La propiedad de opciones es una matriz de todas las opciones en un objeto Select en particular. Hay un elemento (numerado en orden ascendente desde cero) para cada etiqueta

+0

bien, entonces, según su edición, entiendo que selecbox.options es en realidad una matriz de objetos, y no una matriz normal. está bien ? – Dementic

1

Usted puede unirse a una matriz de cadenas, sino una opción que no es una cadena, es un objeto de todo tipo de propiedades como el valor y el texto. ¿Qué debería usar para unirse?

Solo tiene que escribir un bucle para agregar todos los valores que desee.

O use una biblioteca y use alguna función each() para recorrer las opciones.

+0

usar una biblioteca? para esta función? añadir 65k a mi proyecto por una cosa simple? eso es un mal consejo. – Dementic

+0

Quise decir solo cuando ya estás usando una biblioteca. Solo quería aclarar las opciones. – edwin

6

para obtener todos los valores en una matriz:

var options = document.getElementById('selectId').options; 
var values = []; 
var i = 0, len = options.length; 

while (i < len) 
{ 
    values.push(options[i++].value); 
} 
alert(values.join(', ')); 

violín:http://jsfiddle.net/garreh/64pyb/1/


wow un largo camino para hacer algo corto

Bueno puede usar un bucle for, no mucho más corto pero más feo;

for (var options = document.getElementById('selectId').options, 
      values, i = 0, len = options.length; i < len;i++) 
    values.push(options[i].value); 

alert(values.join(', ')); 

nuevo, es una pena que no estás utilizando una biblioteca como jQuery.Usted podría hacer:

$('select > option').map(function() { return this.value; }).get(); 
+0

wow, un largo camino para hacer algo corto :) pero ¡gracias! – Dementic

+0

seleccione> opción sin la s, muy buena http://jsfiddle.net/mplungjan/jwrML/ – mplungjan

3

selecbox.options es una colección (lista de nodos). Puede iterar sobre su elemento como lo hace con una matriz y empujar los miembros de la colección a una matriz real.

Para el registro: en todos los navegadores, pero IE 9 < puede utilizar [].slice.call(selecbox.options); para convertir rápidamente una colección a una matriz.

Así crossbrowser una manera de convertir una colección de lista de nodos a la matriz sería:

function coll2array(coll){ 
    var ret = []; 
    try { 
     ret = [].slice.call(coll) 
    } 
    catch(e) { 
     for (var i =0;i<coll.length;i++){ 
      ret.push(coll[i]); 
     } 
    } 
    return ret; 
} 

[editar ] Hoy en día (ES2015 y superiores) podemos utilizar Array.from([arraylike object]).

o Array.prototype.slice.call([some collection])

+0

thx para la información, pero como mejor práctica prefiero una solución CrossBrowser. – Dementic

+0

También necesita procesar esta nueva matriz de objeto HTMLOptionElement – mplungjan

2

select.options no es una matriz, es un NodeList que comparte algunas de las características de una matriz y así puede ser descrita como array similares. un NodeList no tiene los métodos que tiene una matriz, pero puede call o apply esos métodos. En su caso, usted puede llamar al método unen de esta manera:

var opts = yourSelect.options; 
var str = Array.prototype.join.call(opts, ','); 

alternativa usted puede convertir el NodeList en una verdadera matriz con una técnica similar

// slice returns a new array, which is what we want 
var optsArray = Array.prototype.slice.call(opts); 
+1

Sin embargo, eso devuelve '[object HTMLOptionElement], [object HTMLOptionElement], [object HTMLOptionElement], [object HTMLOptionElement]' – mplungjan

+1

@mplungjan - true, [object HTMLOptionElement] es la resultado de una llamada a Option.toString(). Entonces, usar esta respuesta como una solución es bastante inútil. Mi respuesta explica el por qué? parte de la pregunta de OP aunque – meouw

11

La solución más correcta es la siguiente:

Array.apply(null, selectbox.options) 

Array.apply llama al constructor Array con el primer argumento como el contexto (es decir this) y el segundo argumento que es cualquier objeto tipo array (MDN reference).

Pasamos null para el primer argumento porque no estamos tratando de llamar a un método en un objeto específico, sino más bien un constructor global.

Así que, en general,

Array.apply(null, A) 

Se creará una matriz adecuada que contiene los elementos de cualquier objeto "matriz-como" A.

+0

MDN actualmente [no es muy útil con la compatibilidad del navegador] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply#Browser_compatibility) , pero con algunas pruebas rápidas en Chrome, FF e IE, parece que el navegador moderno es amigable (c) 2016. Muy buena respuesta. – ruffin

+3

Y para obtener solo el texto de esas opciones: Array.apply (null, selextbox.options) .map (function (el) {return el.text;}); – webdevinci

+0

NOTA: 'Array.apply (null, document.querySelector (" select "). Options)' seguirá produciendo '[object HTMLOptionElement], [object HTMLOptionElement], [object HTMLOptionElement], [object HTMLOptionElement]' - de modo que mapeo adicional o looping es necesario para obtener valores y textos – mplungjan