Reputation: 97
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
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
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
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
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