Nicla Marino
Nicla Marino

Reputation: 97

Store array into variables in Javascript

I have an array of inputs, after looping through them using a for loop, is it possible to store each value into a variable?

Here's what I am trying to do specifically: I am building a gradient background generator. I have a total of 6 inputs (rgb for the first color of the gradient and rgb for the second one). I loop through the input array and then I stored each value into a variable (r, g, b, r2, g2, b2) and then use them in the linear-gradient css.

My method doesn't seem to be very functional, so I was wondering if it was possible to store all the input[i] values "automatically" into variables.

const inputs = document.querySelectorAll('input')
const body = document.body;

for (var i = 0; i < inputs.length; i++) {
  inputs[i].addEventListener('change', changeValue);
  inputs[i].addEventListener('mousemove', changeValue);

  function changeValue() {
    let r = inputs[0].value;
    let g = inputs[1].value;
    let b = inputs[2].value;
    let rgb = r + ',' + g + ',' + b;

    let r2 = inputs[3].value;
    let g2 = inputs[4].value;
    let b2 = inputs[5].value;
    let rgb2 = r2 + ',' + g2 + ',' + b2;

    body.style.backgroundImage = `linear-gradient(45deg, rgb(${rgb}), rgb(${rgb2}))`;
  };
}
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">

<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">

Upvotes: 1

Views: 116

Answers (4)

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48610

You can remove all the for loops, by utilizing Array.prototype.forEach and Array.prototype.slice.

I also created a custom shiv (aka polyfill) for EventTarget.prototype.addEventListeners.

EventTarget.prototype.addEventListeners = function(eventNames, listener) {
  eventNames.split(' ').forEach(event => this.addEventListener(event, listener, false))
}

const inputs = document.querySelectorAll('input')

inputs.forEach(input => input.addEventListeners('change mousemove', onChangeValue))

function onChangeValue() {
  let rgb1 = [].slice.call(inputs, 0, 3).map(x => x.value).join(',')
  let rgb2 = [].slice.call(inputs, 3, 6).map(x => x.value).join(',')
  document.body.style.backgroundImage = `linear-gradient(45deg, rgb(${rgb1}), rgb(${rgb2}))`;
};
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">

You could also try to group the components by classes.

EventTarget.prototype.addEventListeners = function(events, listener) {
  events.split(' ').forEach(event => this.addEventListener(event, listener, false));
}

document.querySelectorAll('.color-slider-channel').forEach(input => {
  input.addEventListeners('change mousemove', onChangeValue);
})

function onChangeValue(e) {
  document.body.style.backgroundImage = `linear-gradient(45deg, ${retrieveGradientStops()})`;
};

function retrieveGradientStops() {
  return [...document.querySelectorAll('.color-slider-rgb')].map(s => {
    return 'rgb(' + [...s.querySelectorAll('.color-slider-channel')].map(c => c.value).join(',') + ')';
  }).join(', ');
}
<div class="color-sliders">
  <div class="color-slider-rgb">
    <input type="range" class="color-slider-channel" min="0" max="255">
    <input type="range" class="color-slider-channel" min="0" max="255">
    <input type="range" class="color-slider-channel" min="0" max="255">
  </div>
  <div class="color-slider-rgb">
    <input type="range" class="color-slider-channel" min="0" max="255">
    <input type="range" class="color-slider-channel" min="0" max="255">
    <input type="range" class="color-slider-channel" min="0" max="255">
  </div>
</div>

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386578

You could get the values by their id.

function changeValue() {
    const mapId = id => document.getElementById(id).value || 0;
    var [rgb, rgb2] = inputs.map(groups => groups.map(mapId).join(','));

    document.body.style.backgroundImage = `linear-gradient(45deg, rgb(${rgb}), rgb(${rgb2}))`;
}

var inputs = [['r1', 'g1', 'b2'], ['r2', 'g2', 'b2']];

inputs.forEach(group => group.forEach(id => {
    document.getElementById(id).addEventListener('change', changeValue);
    document.getElementById(id).addEventListener('mousemove', changeValue);
}));
<input id="r1" type="range" min="0" max="255">
<input id="g1" type="range" min="0" max="255">
<input id="b1" type="range" min="0" max="255"><br>
<input id="r2" type="range" min="0" max="255">
<input id="g2" type="range" min="0" max="255">
<input id="b2" type="range" min="0" max="255">

Upvotes: 0

James Coyle
James Coyle

Reputation: 10398

If you're using ES6 you can use a destructuring assignment.

You would do something like:

let [r, g, b, r2, g2, b2] = Array.from(inputs).map((x) => x.value);

Example:

const arr = [234,124,233, 25,233,21]

let [r, g, b, r2, g2, b2] = arr;

console.log(r, g, b)
console.log(r2, g2, b2)

Upvotes: 1

Alberto Trindade Tavares
Alberto Trindade Tavares

Reputation: 10366

You can simplify your code by using Array destructuring:

const inputs = [...document.querySelectorAll('input')];
const body = document.body;

for (var i = 0; i < inputs.length; i++) {
  inputs[i].addEventListener('change', changeValue);
  inputs[i].addEventListener('mousemove', changeValue);

  function changeValue() {
    let [r, g, b, r2, g2, b2] = inputs.map((x) => x.value);

    let rgb = r + ',' + g + ',' + b;
    let rgb2 = r2 + ',' + g2 + ',' + b2;

    body.style.backgroundImage = `linear-gradient(45deg, rgb(${rgb}), rgb(${rgb2}))`;
  };
}
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">

<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">

Upvotes: 0

Related Questions