Looping through an array and setting variables - javascript

What I have so far:
http://codepen.io/anon/pen/umHzl?editors=101
You notice that you can click a box and unclick it. What I would like is that when a certain button is clicked all other buttons are unclicked(turn back to normal color).
My attempt at this:
for (var i =0; i < booths.length; i++){
var obj = booths[i]
obj.e1['fill'] = obj['color'];
obj.e1['checked'] = 'false';
$("#"+obj.name).remove();
}
I know that the color is in the e1/rectangle object of the box, but I do not know how to change/access that variable. It says obj.e1 is undefined. If I do obj['fill'] it still doesn't work.
How would I change the colors from such a loop (or something similar).

It's not e1, it's el (lowercase 'L'). And you'll still want to use the attr() function, e.g.:
for (var i =0; i < booths.length; i++){
var obj = booths[i]
obj.el.attr('fill', obj['color']);
obj.el.attr('checked', 'false');
$("#"+obj.name).remove();
}
Example: http://codepen.io/paulroub/pen/yFwCq

Related

How to add onclick functions in an array of buttons using a for loop properly?

I'm making a kind of HTML calculator to test something I have in mind.
I've used a for loop to create the buttons of the keypad. The display is a text field.
Then I used a for loop to add the functions in the buttons:
for (var i = 0; i < 10; i++)
{
buttons[i].onclick = function()
{
display.value += i;
};
}
What I was trying to do is to make, for example, buttons[0] add "0" to the value of the text field when clicked. Instead, clicking any button added "10" in the text field. Why? How can I make it right?
You almost got it right , you just need to change var to let in your loop declaration :
for (let i = 0; i < 10; i++)
{
buttons[i].onclick = function()
{
display.value += i;
};
}
What's the difference between using "let" and "var"? Here you can get more info about your issue.
Your problem is that you are referencing i directly in your functions that you are binding to your Buttons. i will actually continue to exist even after you bound all your events, and its value will be the last value of the iteration 10. So whenever a click function runs, it looks up i and finds the last value you set (10) and takes that value. What you want to do is add a constant reference instead - so that you bind that value you have during the loop and keep that reference forever, no matter how i might change later.
for (var i = 0; i < 3; i++) {
const localValue = i
buttons[i].onclick = function()
{
counter += localValue;
counterElement.innerHTML = counter
};
}
I created a small example fiddle here: https://jsfiddle.net/4k8cds9n/ if you run this you should see the buttons in action. Some related reading for this topic would be around scopes in javascript, one good article: https://scotch.io/tutorials/understanding-scope-in-javascript

Undefined is not an object in Dropdown

I want my code to show the menu by adding a slactive class and change the value of an input from ddown collection. I have some code, which isn't working as console says that on line 9 nor ddown[i], nor slitems[j] are objects, as they're undefined. How to fix this?
var slitems = document.getElementsByClassName('slitem');
ddown = document.getElementsByClassName('ddown');
for(i=0; i<ddown.length; i++) {
ddown[i].addEventListener('click', function(){document.getElementById('sl'+i).classList.add('slactive');valueChange()});
}
function valueChange(){
for(j=0;j<slitems.length;j++){
slitems[j].addEventListener('click', function(){
ddown[i].value = slitems[j].value;
document.getElementById('sl'+i).classList.remove('slactive');
});
}
}
P.S. slitems is a collection of menu elements.
Look, what you are doing has at least two flaws:
1st: when doing this: for(i=0; i < ddown.length; i++) ... you are declaring a global variable named i that, at the end of loop will have the value ddown.length; so, in valueChange, it will always have the same value
2nd: i is set to ddown.length, that is a position that doesn´t exists in the array, hence the error you got.
To fix this, set i as a local variable using var, and pass it as an argument:
var slitems = document.getElementsByClassName('slitem');
ddown = document.getElementsByClassName('ddown');
for(var i=0; i<ddown.length; i++) {
ddown[i].setAttribute("data-index", i);
ddown[i].addEventListener('click', function(e){
var i = e.target.dataset.index;
document.getElementById('sl'+i).classList.add('slactive');valueChange(i)
});
}
function valueChange(i){
for(var j=0;j<slitems.length;j++){
slitems[j].setAttribute("data-index", j);
slitems[j].setAttribute("data-index2", i);
slitems[j].addEventListener('click', function(e){
var j = e.target.dataset.index;
var i = e.target.dataset.index2;
ddown[i].value = slitems[j].value;
document.getElementById('sl'+i).classList.remove('slactive');
});
}
}
EDIT
Changed the code to add the variables used in iterators as node attributes, what should fix the variable scope issue.

unable to push each element that is named tab into an array after pulling the dom object

In the developer tools it shows that i was able to pull all the elements that i needed to but the issue is i cannot push them to the array, it stays empty. Unfortunately i am not allowed to use jquery. I have done so much research and just unable to find exactly what i need.
/*
Author:Anthony Weed
Date:2/20/2015
Filename: menus.js
*/
window.addEventListener('load',setTabs);
var currentTab = null;
var maxZ = 1;
var i=0;
function setTabs(){
var menuTabs = [];
var allElements = document.getElementById('page').getElementsByTagName('*');
for(var i=0; i < allElements.length; i++){
if (allElements.children == 'LI.tab'){
menuTabs.push(allElements[i]);
}
else {
continue;
}
i++
}
console.log(allElements);
console.log(menuTabs);
}
Try this:
for(var i=0; i < allElements.length; i++){
if (allElements.children == 'LI.tab'){
var newAryElement = allElements[1];
menuTabs.push(newAryElement);
}
i++
}
This might not solve your problem, but I suspect that it will reveal newAryElement to be an array itself, which you will then need to parse.
Your problem is this line:
if (allElements.children == 'LI.tab'){
allElements.children is referencing something that isn't there. allElements is an HTMLCollection, which is kind of like an array, but it's an object.
I'm a little unclear in what you're trying to do, so I can't really offer a way to make this work, but this is certainly the problem. Depending on what you're trying to do, you might want to be referencing something like:
if (allElements.item(i).tagName == somethingHere ) {
Here's the reference for getElementsByTagName().

Loop through colours array with jQuery

I'm trying to give each div a different background colour. Here is my current code:
http://jsfiddle.net/Uy2FX/2/
var imgColours = ['#FCCF94', '#C4C9E5', '#ADE3D6'];
for (i=0; i < imgColours; i++) {
$('.img').css({backgroundColor: imgColours[0]});
}
However, I'm not quite sure where this is going wrong. I understand that's probably too simple to work, but in my mind it makes sense. Could someone point me in the right direction?
There are some relevant errors in your code.
This is probably what you wanted to do:
// V1 : Basic
var imgColours = ['#FCCF94', '#C4C9E5', '#ADE3D6'];
for (var i=0; i < imgColours.length; i++) {
$('.img:eq('+i+')').css({backgroundColor: imgColours[i]});
}
But if you want to get a random color from your array, for any number of divs, and also optimise your jQuery code a bit for better performance:
// V2 : random colors
var $imgs = $('#boxes1').find('.box'),
imgsCount = $imgs.length,
coloursCount = imgColours.length;
for (var i=0; i < imgsCount; i++) {
var rnd = Math.floor(Math.random() * coloursCount),
color = imgColours[rnd];
$imgs.eq(i).css({backgroundColor: color});
}
Or, if you want to loop through the colours following the order of the array, just change the loop:
// V3 : sequential colors
// Add V2 variables here
for (var i=0; i < imgsCount; i++) {
var color = imgColours[i%coloursCount];
$imgs.eq(i).css({backgroundColor: color});
}
UPDATED FIDDLE: http://jsfiddle.net/Uy2FX/12/
For some very basic tips on jQuery selectors performance: http://www.sitepoint.com/efficient-jquery-selectors/
You are always assigning imgColours[0] to EVERY div. I think what you are looking for is imgColours[i]
You will also need to use imgColours.length to tell your loop how long the array is.
You are also grabbing all HTML elements with the class of img, so this will change all of them each time.
To grab each element separately, you can use the CSS nth-of-type selector. Basically you can just do something like
$(".img:nth-of-type(" + i + ")")
You need to use imgColours.length
The for loop has no idea how long the array is otherwise
Edit: What's the point in this for loop if you end up using imgColours[0] anyways? If you want to loop each color, use i instead of 0.
And either way, this will not achieve a different background per div.
Try selecting by className (I'm going to use vanilla.js because it's simple)
var elements = document.getElementsByClassName("img");
for (var i = 0; i<elements.length; i++) {
var color = imgColours[Math.floor(Math.random()*imgColours.length)]; //get a RANDOM color change me if needed
elements[i].style.backgroundColor = color;
}
How about this?
var ec = 0;
var i = 0;
for(ec; ec < elements.length; ec++, i++) {
elements[ec].style.backgroundColor = imgColours[i];
if(i == (imgColours.length - 1)) i = -1;
}
http://jsfiddle.net/y2dq3/

JavaScript loop through all elements with tagname, alert

var all = document.getElementsByTagName("a");
for (var i=0, max=all.length; i < max; i++) {
alert(x.innerHTML);
}
The purpose of this script is obvious: it tries to loop through all the elements with the tag name a, and alert the contents of each one.
It doesn't run right.
It works fine, with one element, it alerts it's contents, but when there are more then one, it starts echoing undefined for each.
You haven't provided a definition for x. Try this:
var all = document.getElementsByTagName("a");
for(var i = 0, max = all.length; i < max; i++)
{
alert(all[i].innerHTML);
}
you should use alert(all[i].innerHTML). x is undefined
x is obviously undefined. You need to have something like:
var all = document.getElementsByTagName("a");
for (var i = 0, x; x = all[i++];)
alert(x.innerHTML);
However alert in a loop is really annoying, I would suggest to use console.log instead.
Tips: in browsers that supports already for…of, such Firefox, you can simply have:
var all = document.getElementsByTagName("a");
for (var x of all)
console.log(x.innerHTML);
Of course you can't use that on webside across browsers, it's just something good to know in the upcoming ES6 – or if you're going to write a Firefox's extension for instance.

Categories

Resources