javascript: var i is not defined? (clearly defined) - javascript

WHAT I WANT TO HAPPEN
So what I want to happen is function partA() to click button [z] every 2 seconds. The button that is being clicked should change, because the script is a looping script, so for instance. The first loop, it would click button 1, then button 2, then button 3, because var z = 1 + i++. Is this possible? z is supposed to equal the number 1, plus the loop number. This should loop as long as variable i is less than 50.
WHAT IS HAPPENING
It works properly, looping and all, if I test the script without variable z. However, without variable z, I have to manually change the number that would equal z, which is painstaking, and annoying.
var z = 1 + i++
for(i=0;i<50;i++) {
setInterval(partA, 2000);
function partA() {
buttons = document.getElementsByTagName('button');
document.getElementsByTagName('button')[z].click();
}
}
Should i++ be defined another way? The error I'm getting when running the script in console is:
Uncaught ReferenceError: i is not defined (...)
at :2:13
at Object.InjectedScript._evaluateOn (:878:140)
at Object.InjectedScript._evaluateAndWrap (:811:34)
at Object.InjectedScript.evaluate (:667:21)

There's a couple of suggestions I could advise with your code so I'll try and address each one individually.
Firstly define your function outside of your loop. If you would like to know the reasons behind this please read: Don't make functions within a loop
Secondly you should really declare i as a variable to set the scope to which it applies. Some good information on this is at: Declaring variables without var keyword
Thirdly when you run your loop you could run the code inside an IIFE. The reason for this is when you run setInterval, by the time it runs i will actually be 3 (or the last number of your loop). This is due to the asynchronous nature of setInterval, and that the reference to i is bound to the function, not the value of i.
Example
for(var i=0;i<3;i++) {
(function(i) {
setInterval(clickButton(i), 2000);
})(i)
}
function clickButton(idx) {
return function() {
buttons = document.getElementsByTagName('button');
document.getElementsByTagName('button')[idx].click();
}
}
JSBin Demo
http://jsbin.com/harigewuze/edit?html,js,output

Why are you trying to define z outside the loop? Just use i.
for (var i = 0; i < 50; i++) {
...
document.getElementsByTagName('button')[i].click();
}

without changing your code too much I would write it like this...
you know its looping 50 times, you know i is incrementing from 0 to 49, use i to change the button name and you don't need z...
for(i=0;i<50;i++) {
setInterval(partA, 2000);
function partA() {
buttons = document.getElementsByTagName('button');
document.getElementsByTagName('button')[i + 1].click();
}
}

1) This is how you want your code to look like :
var z;
for(i=0;i<50;i++) {
z=i;
setInterval(partA, 2000);
}
function partA() {
buttons = document.getElementsByTagName('button');
document.getElementsByTagName('button')[z].click();
}
2) Unfortunately, in javascript you have a problem with this code due to the fact of scopes. My recommendation is to read this link first http://www.mennovanslooten.nl/blog/post/62 and understand how it works.
If you did understand it, then thumb up..you just promoted yourself to a higher level in javascript ;)
3) If you are still having issues, post it on JSFiddle

Related

How to have a variable increase over time (JS)

i was wondering how to make a variable go up over time, ive tried to do this -->
var i = 1;
var c = document.getElementById("click");
function workers() {
if (click >= workers*50000)) {
click += -(workers*50000)
click += i++
c.innerHTML = click;
}
}
but it hasnt worked, how do i fix this?
you could do this
let i = 0;
// instead of 2000 insert the frequency of the wanted update (in milliseconds)
const incrementInterval = setInterval(() => i++, 2000)
// when you want it to stop it
clearInterval(incrementInterval)
anyway, i don't really understand how the code supplied with the question has anything to do with it
You have an element and a variable 'click', which tells me you're really not wanting to grow over time per se, but rather grow with every click.
Another difficulty is finding out what you're trying to do with multiplying by 50000. I am assuming you are trying to reset the count after 50000.
One big thing you're missing is the actual association of the click event to your 'click' HTML element. Below, I'm using addEventListener to do that. From there, I'm resetting the counter to '1' if 'i' goes above '5' (I use 5 just to show the reset in a reasonable number of clicks). Then I take the value of 'i' and put it into the innerHTML label of the element that triggered the event.
var i = 1;
document
.getElementById("click")
.addEventListener('click', function(e) {
if (i > 5)
i = 1;
e.target.innerHTML = `click: ${i++}`;
})
<div id='click'>click<div>
Define your question better. What is your goal? What has your code achieved? What result are you getting and how is it different than your expectations? What is 'i' meant to be used for? How does it interact with the function? Why are you multiplying it with 50000? Is workers a separate variable that's globally defined and not shown? Communication is an important skill in this field, and comments are often helpful tools to document your code for others to understand.
I think an alternative answer could be formatted in this way:
let i = 0;
function increment(){
i++;
document.querySelector('h3').textContent = i
}
document.querySelector('button').addEventListener('click',increment)
<button>Click Me</button>
<h3>0</h3>

calling a function in for loop giving infinite loop but same works fine in while loop

So i was working on a function which takes anything as argument and console logs it inside a box or a cell. This is what i came up with:
var horiz='━';
var vert='┃';
var ulcor='┏';
var urcor='┓';
var blcor='┗';
var brcor='┛';
//create a cell/box
var cell=(d='')=>{
let h='';
if(d==undefined||d==null){
throw('cell needs an argument');
}
len=d.toString().length;
for(i=0;i<3;i++){
if(i==0){
for(j=0;j<len;j++){
h+=horiz;
}
if(i==0) console.log(ulcor+h+urcor);
}
if(i==1){
console.log(`${vert}${d}${vert}`);
}
if(i==2){
console.log(blcor+h+brcor);
}
}
}
Now when i was testing this i did following
cell('index');
cell(1);
gave following output:
┏━━━━━┓
┃index┃
┗━━━━━┛
┏━┓
┃1┃
┗━┛
and did other testing as well and it worked pretty well until i did the following test:
for(i=0;i<5;i++){
cell(i)
}
Above code should give me cells/boxes with 1,2,3,4 but instead this gave me an infinite loop and what i noticed is that its only printing cells with 4 (not 1,2 or 3) but infinite times.
And now here is the fun part. When I do following:
n=1;
while(n<10){
cell(n);
n+=1;
}
above code gives desired result and works fine.
Weird!! just Couldn't figure out why its running infinite times when i used it in the for loop but while loop works good. If any sort of improvement required in the code then please do mention it:)
When you declare a variable without the var, let, or const keywords, that variable is an implicit global. In your cell function, you use for(i=0;i<3;i++) where i is declared without a keyword.
Your calling for loop for(i=0;i<5;i++){ cell(i) } also uses i without a keyword which makes i refer to the same global variable. So your call function is actually manipulating i from within the function which makes the for loop behave in the unintended manner. The while loop uses a different variable, n, which is why it doesn't have the same problem.
Try changing the for loop inside call to for(let i = 0; i < 3; i++) to limit the scope of i. And, in general, use let and const to declare ALL variables, even (and especially) the ones in for loops.

JavaScript For Loop Breaking Early

Why would a for loop terminate early in JavaScript? For some reason my outer for loop terminates after the first repetition. I am new to JavaScript but would expect something like this to work in Java.
function check(){
var elements = document.getElementById('fields').children;
var filteredMolecules = molecules;
console.log(elements.length);
for (i = 0; i < elements.length; i++) {
console.log(elements[i].id)
filterMolecules(filteredMolecules, elements[i].id, 0, 10);
}
}
function filterMolecules(molecules, parameter, lower, upper){
console.log('filtering');
var filteredMolecules = [];
for (i=0;i<molecules.length;i++){
var value = molecules[i].val()[parameter];
filteredMolecules.push(molecules[i]);
}
molecules=filteredMolecules;
}
In check(), I loop through elements which contains 22 items as shown by the first console.log(elements.length). If I remove the method filterMolecules(...) then all 22 IDs are logged. However, with the code as is, only the first id is logged.
I believe the filterMolecules method which should run elements.length number of times is causing the outer for loop to not work. Could someone please explain why this is happening. If relevant, in filterMolecules(...) the data is retrieved from Google Firebase with molecules[i].val()[parameter]. Additionally, both methods use the global variable molecules (line 3 and line 14)
When you don't declare variables in javascript you end up using globals (which can be a difficult to spot source of bugs). So here you are using the same global variable i for both loops. When you start looping thought molecules you are accidentally incrementing the counter loop of your first for. Use different variables or define them with :
for (let i=0;i<molecules.length;i++)
Which will give each loop its own version of i.
In this case, since the declarations are inside individual functions, you could use var too:
for (var i=0;i<molecules.length;i++) {
// etc.
}

Why the eval() is not working with array

What's wrong with this code? Can anyone help out?
var read=new Array("i=10","j=20","k=i*j");
for(var i=0;i<read.length;i++)
{
alert(eval(read[i]));
}
Expecting output:
alert three times with values 10,20,200.
But actual output:
But alert Once with value 10.
When the loop executes the first time, you are setting i = 10, with eval. So the loop breaks out immediately.
So, you might want to change the loop variable to something else, like this
var read = new Array("i=10","j=20","k=i*j");
for(var idx=0; idx < read.length; idx++)
{
console.log(eval(read[idx]));
}
Output
10
20
200
Note: Please make sure that you read this question and the answers to that question, before using eval in your code.
Try this code
var read=new Array("i=10","j=20","k=i*j");
for(var index=0;index<read.length;index++)
{
alert(eval(read[index]));
}
while the loop is executing, at the first execution of i=10 the i variable is set to 10; so loop will be terminated because of the condition i<read.length (here... 10<3) remains false.
see the eval() tutorial.

For Loop repeats first loop twice

I have this for loop, and it seems to be repeating the first loop twice (x=0) and then not doing the last one (x=2)
for (x=0;x<=2;x++)
{
if (document.getElementById("sub"+catCount+x).value != "")
{
if (nonums.test(document.getElementById("sub"+catCount+x).value))
{
total = total + parseFloat(document.getElementById("sub"+catCount+x).value);
}
}
alert(x);
}
In other words, I get two alert boxes with "0" in them, then one with "1" in it, and that's it.
Can anyone tell me what I'm not seeing here? Why doesn't it just progress through the loop normally (0,1,2)?
that is literally the only spot I use
the variable x on any page.
It works for me.
for (x=0;x<=2;x++)
{
alert(x);
}
You can test it at console.
I don't think you want the variable x to be global in scope. Try it with the "var" keyword:
for (var x=0;x<=2;x++)
...
I can paste this in my address bar and it will produce 0, 1, 2.
javascript:for (var x=0;x<=2;x++) {alert(x);}
I tried it in IE, FF and Chrome.

Categories

Resources