Javascript selecbox.options to array?

2019-03-17 23:04发布

From what I understand a option elements that popuate select elements in HTML are an array.
So basically what i want to do is return an array string that is separated by commas.

Tried to do selecbox.options.join(',');, but got an error that its not supported; anyone have an idea why?

6条回答
ゆ 、 Hurt°
2楼-- · 2019-03-17 23:09

You can join an array of strings, but an option is not a string, it's an object with all kinds of properties like value and text. Which should it use to join?

You just have to write a loop to append all values you want.

Or use a library and use some each() function to loop through the options.

查看更多
闹够了就滚
3楼-- · 2019-03-17 23:17

It is not an array. It is an object. It is "array-like"

from http://api.jquery.com/jQuery.each/ which CAN iterate over either:

Iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties.

Each HTML Option element has a value and a text and some more attributes.

A simple for loop can be used

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);
}

the Array.apply posted by typeracer will return an array of HTMLOptionElements which still needs to be looped over or mapped to get at the values and texts

Here are a few versions that will return the same.

This fiddle will run in IE11 too

var vals, sel = document.querySelector("select"), show=function(vals) {$("#result").append("[" + vals.join("][") + "]<hr/>");}
var supportsES6 = function() {try{new Function("(a = 0) => a");return true;}catch (err) {return false;  }}();


// 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);

// ES6 JS using spread and map of HTMLOptionElements - note the fat arrow and el
if (supportsES6) 
  document.write(`<script>

  vals = [...sel.options].map(el => el.value);

show(vals);
<\/script>`
);
<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><br/> 
The above select has the following option values:<br/>
<span id="result"></span>

查看更多
成全新的幸福
4楼-- · 2019-03-17 23:28

The most concise solution is this:

Array.apply(null, selectbox.options)

Array.apply calls the Array constructor with the first argument as the context (i.e. this) and the second argument which is any array-like object (MDN reference).

We pass null for the first argument because we're not trying to call a method on a specific object, but rather a global constructor.

So in general,

Array.apply(null, A)

Will create a proper array containing the elements of any "array-like" object A.

查看更多
混吃等死
5楼-- · 2019-03-17 23:30

To get all the values into an array:

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(', '));

Fiddle: http://jsfiddle.net/garreh/64pyb/1/


wow a long way to do something short

Well you can use a for loop, not much shorter but more ugly;

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

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

Then again it's a shame you're not using a library like jQuery. You could do:

$('select > option').map(function() { return this.value; }).get();
查看更多
Root(大扎)
6楼-- · 2019-03-17 23:30

selecbox.options is a (nodeList) collection. You can iterate over it's element like you do with an array an push the members of the collection to a real array.

For the record: in all browsers but IE<9 you can use [].slice.call(selecbox.options);1 to quickly convert a collection to an array.

So a crossbrowser way to convert a nodeList collection to array would be:

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

[edit] Nowadays (ES2015 and up) we can use Array.from([arraylike object]).

1 or Array.prototype.slice.call([some collection])

查看更多
你好瞎i
7楼-- · 2019-03-17 23:30

select.options is not an array, it is a NodeList which shares some of the features of an array and so can be described as array like. a NodeList doesn't have the methods that an Array has, but you can call or apply those methods to it. In your case you can call the join method like this:

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

Alternatively you could convert the NodeList into a true Array with a similar technique

// slice returns a new array, which is what we want
var optsArray = Array.prototype.slice.call( opts );
查看更多
登录 后发表回答