javascript for loop not behaving as expected - javascript

I know this is really basic but I am new to Javascript
This is a piece of code from a battleship game I am working on for a class
function displayMyBoats(ship){
for (var i = 0; i<ship.length; i++)
{
alert("ship.length = " + ship.length);
alert("Ship[i]= " + ship[i]);
document.getElementById( "Set_" + ship[i] ).src = fnImageShip;
alert("i = " + i);
}
}
I am testing with a ship array that is 5 elements. Everything works fine until it reaches 5, then all of a sudden it thinks the length of the array is 8.
There is no code to increase the length of ship array, so what would cause it to add to the length of the array?
The alerts are my testing to see what all the values are at.

To give you a hint, try adding an alert whenever your script is either entering or exiting the displayMyBoats(). Suddenly jumping to 8 indicates that it's entering the method a second time, this time with a ship of len 8.
Confirm or deny this theory by adding this alert after your for loop block:
alert('exiting displayMyBoats()');`

Perhaps you see more if you use console.log(ship); instead of alert(); - if you are using Firebug/Console.

Related

How to check if a variable has increased (JavaScript)

I want my code to check if a variable has increased. For example, I have a function that looks for the letter A in a text box, which runs every time a key is pressed. Then it counts the number of A's it has found. Then I want to alert me everytime a new A is written. I thought I could do this easily by just checking if the var numberOfA has increased in an if statement, and if it has to alert me, but I can't figure it out. I have tried using ++ and =/== in my if statement, but it alerts me every single time a letter is typed, instead of only everytime an A has been typed. All help is appreciated, I'm pretty new at this.
function checkForA(){
var sentence = document.getElementById("userText").value.match(/a/g);
var numberOfA = sentence.length;
if (numberOfA = numberOfA +1) {
alert(" The letter A has been typed ");
}
}
Several problems.
When you write numberOfA = numberOfA + 1, you actually assign a value to numberOfA. Use a === b if you want to test equality.
Also, if you decide to use numberOfA to store the previous count, then you need to compare that with the current sentence.length value.
As a side note: if you are new, then invest time in learning how to use the debugger (e.g. in the browser dev tools). It will save you a lot of time and help you really understand what is happening.
You can not check numberOfA = numberOfA + 1 in your if statement. You can try this -
var numberOfA = 0;
function checkForA(){
var sentence = document.getElementById("userText").value.match(/a/g);
if (sentence.length > numberOfA) {
numberOfA = sentence.length;
alert("The letter A has been typed. In your sentence A has found "+numberOfA+" times.");
}
}

JSLint confusion in Javascript alerts are not declared

Hey so I'm using JSLint under the assumption I'm using a browser and tolerating multiple vars and whitespace mess.
The whole program works, but I have a few problems, according to JSLint. First off, I'm trying to use alert(string) to make pop-up error messages, but JSLint is telling me the alerts are undeclared, I haven't found a resource on the internet that's explained how to make this not happen yet.
Secondly, I have loops that look like this:
function setMixedList() {
"use strict";
clearResults();
var n = "0";
var l = "0";
var text = "";
while (n < numList.length && l < letList.length) {
document.getElementById("listInput").value =
text += numList[n] + letList[l];
n ++;
l ++;
}
This loop in particular takes two separate arrays and mixes them together in order; one containing numbers (1-7) and the other containing letters (a-g) in a way so they appear in a text box like this:
1 a 2 b 3 c 4 d 5 e 6 f 7 g
JSLint doesn't like two things about this. The first is that in the
document.getElementById("listInput").value =
text += numList[n] + letList[l];
section of the loop, JSLint tells me the "+=" is unexpected. When I edit that to:
text = text + numList[n] + letList[l];
JSLint tells me the "=" is unexpected and I'm not sure how to take these things out without making my program unable to work.
The other important part of this is the
n ++;
l ++;
section of code. I know JSLint doesn't like ++, but if I make the code
n+= 1;
l+= 1;
The string doesn't come out right, with some characters undefined because I'm not just dealing with numbers. Anybody know how to fix these problems?
To answer the first part
JSLint is telling me the alert
This can be resolved by following one of the way . In jslint options set
"devel:true" which will enables things like Alert, console,prompt.Check this link to know more about it.
Secondly set browser option set to true in your .jshintrc and use window.alert instead of alert

Javascript Random Guess Game

https://jsfiddle.net/andrew_jsfiddle/eyLyqajz/1/
Assignment 1 - Using your JSFiddle account you are going to create a guessing game, only it will be the computer doing the guessing. Here is how it works - the computer will ask you for a number between 1 and 1000, it will check first to make sure your input is within the bounds.
Once you enter the number it will guess the number and do a comparison with the number you entered. It will output the results of the guess and continue to do this until it gets the correct answer. This is what the output of the program will look like (if I enter 329)
For this attempt I did:
var guessnum= new Guessnum(1000);
document.getElementById("click").onclick= function() {
guesslist()};
function guesslist() {
document.getElementById('guessnum').innerHTML= InsertGuess();
}
function InsertGuess() {
for (var a= 0; a < guessnum.length; a++){
guessnum[a] = Math.floor((Math.random() * 1000) + 1);
}
var show_guess="";
for (i=0; i < guessnum.length; i++){
show_array += "You guess" + guessnum[i] + "of " + i + "<br>";
}
return document.getElementById('guess').innerHTML=show_array;
}
Use a listener on the input with a global variable that contains the random number
var myRandomNumber;
input.addEventListener('input', function(){
}
)
You'll need to click first on the button though.
Fiddle
My friend, I think you are really confused. It wouldn't help to just create it for you. Break down the requirements to actionable steps and start from scratch. You want to create a guess game that you set a number. Think it as simply as possible:
Action 1 - Set a number -->
Create the field
Action 2 - Check if number is valid(1-1000) -->
Get the value entered and make the necessary checks
Action 3 - Computer tries to guess by selecting a num up to 1000 -->
Generate random num from 1-1000
Action 4 - Compare number with the one you set before -->
Simple comparison of generated number and the selected one
Action 5 - Proceed as needed -->
If it's the exact number it won and it will stop!
If it's higher then the next guesses should have this number as highest limit.
If it's lower then the next guesses should have this number as lowest limit.
Action 6 - Show guess and result of comparison --> Simply show the results of the previous actions
Action 7 - If not successful guess --> repeat until the number is guessed
Try to apply this kind of logic to all these problems.

For loop index undefined in IE9 for initial pass

On this page: http://koncordia.marketingassociates.com/19892arc/
I have a slideshow that I created custom prev/next links for. Each selection you make on the page advances it one slide forward. The progress bar at the top allows you to click a previous slide, and jump more than one back if you want (you can go from step 4 or step 1 for example).
This multi-step jump works fine in all the current major browsers, but the client uses IE9, and this is where I do not understand the source of the issue.
The following are the relevant methods in this issue. To mimic a user jumping back one or more slides I have a for loop iterate over simulatePrevClick() as many times as necessary; it's not sexy but it works.
The issue arises on the initial pass in IE9. The console spits out "undefined" for the first pass, but it says 0 for all other browsers (including IE 10 and 11) which is correct. If I remove the method call within the loop the iteration works perfectly, so it has something to do with the .click() event or way the method is called, but I don't know what.
No matter what, IE9 will show the immediate previous slide no matter how many they click back; the progress bar be out of sync if they click back more than one in this instance. The undefined result is not showing as an error, either.
//Highlight the right number of progress buttons
highlightProgressBar: function( slideNumber ) {
$(".btn-progress").attr('disabled', 'disabled').removeClass('active'); //Disabled all
$("#progress-wrapper a:lt(" + slideNumber + ")").removeAttr('disabled'); //Disable select number
$("#progress-wrapper a:eq(" + (slideNumber - 1) + ")").addClass('active'); //Add active to the specified button clicked
},
simulateNextClick: function () {
//The value of this must match what the responsiveslides function creates for the prev/next buttons (seen when you inspect element)
$(".transparent-btns_nav.transparent-btns1_nav.next").click();
},
simulatePrevClick: function () {
//The value of this must match what the responsiveslides function creates for the prev/next buttons (seen when you inspect element)
$(".transparent-btns_nav.transparent-btns1_nav.prev").click();
},
toggleProgressBar: function( clickedSlideNumber, activeSlideNumber ) {
var numSlides = activeSlideNumber - clickedSlideNumber;
for (var i=0; i < numSlides; i++) { //Anticipate user may click more than one step back
this.simulatePrevClick();
console.log(i); // **shows "undefined" on first pass in IE9 only**
}
this.highlightProgressBar(clickedSlideNumber);
}
Try to move the var i = 0 declaration out of the loop.
var i = 0;
for (; i < numSlides; i++) {}
It's really strange that that should happen.
This is just a guess, but I looked through the rest of your source code, and its possible that the root of your problem could be due to whenever you actually implement your toggleProgressBar function, in this area:
$(".btn-progress").click(function() {
var currentSlideID = $("#progress-wrapper").find('a.active').attr('id').split("-");
var clickedSlideID = $(this).attr('id').split("-");
slideFn.toggleProgressBar( clickedSlideID[1], currentSlideID[1] );
});
If I see right, your toggleProgressBar wants to accepts two numbers. However, what you're passing in are string literals:
slideFn.toggleProgressBar( "2", "1" );
ID attributes are output as strings, not numbers. I just tested the following in Chrome, and it worked:
"2" - "1" === 1 //true
This is because I guess V8 (Chrome's JS engine) coerces the two string literals into numbers. However, (while I have not tested it), this tells me that it's possible that IE might not be coercing the two strings into numbers (like I said, I don't know this for a fact, but this is something you might try debugging). Try this and see if it has any effect:
//first option
slideFn.toggleProgressBar( +clickedSlideID[1], +currentSlideID[1] );
//the + sign will typecast your strings into numbers
//second option
slideFn.toggleProgressBar( parseInt(clickedSlideID[1]), parseInt(currentSlideID[1]) );
However, in my experience, parseInt runs a little bit slower than using + to typecast the strings into numbers.
IE uses the Chakra JS engine, which I believe follows the standards of ECMAScript 3, which is from 1999. I haven't read through the standard, but it's worth considering the possibility that it has something to do with the issue.
Edit
Here's your problem:
$("#progress-wrapper").find('a.active') ==> []
The first time, there are no a.active elements. Thus, whenever you try to call split on an empty array, it throws a TypeError.
You need to give your first .btn-progress the class active, because the first time around, your first .btn-progress looks like this:
1
There's no active class. Only subsequent .btn-progress elements receive the class active whenever you click the .btn-continue. Your first one never does. Therefore, clickedSlideID[1] and currentSlideID[1] are undefined the first go around. It probably breaks in IE9 because IE9 doesn't understand i < undefined, but it's possible that other more modern browsers go ahead and execute anyway.
Somewhere in the beginning of your code, then, you need to do something like this:
$('.btn-progress').eq(0).addClass('active');
I just tried this in the console on your page, and it worked just fine. After I added the class active to the fist .btn-progress, currentSlideID[1] was now 1, and not undefined.

Javascript: TypeError variable is undefined

I am currently building a small web application with similar functionality across all modules. I want to code small generic functions so that all programmers next to me, call these functions and these functions return necessary but important data for them to implement their functionality. In this example, I am trying to deal with the typical "choose true or false" exercise. So from the template.php they call this function:
function checkAnswers(){
var radiobuttons = document.form1.exer1;
var correctAnswers = answers(); //this is an array of string
var checkedAnswers = checkExerciseRB(radiobuttons, 2, correctAnswers);
for(i=0; i<checkedAnswers.length; i++){
alert(checkedAnswers[i]);
}
}
Function checkExerciseRB is my generic function, it is called from checkAnswers.
function checkExerciseRB(rbuttons, opciones, correct){
var answers = new Array();
var control = 0;
for(i=0; i<rbuttons.length; i++){
var noPick="true";
for(j=0; j<opciones; j++){
if(rbuttons[control+j].checked){
if(rbuttons[control+j].value==correct[i]){
answers[i]= 1;
noPick="false";
break;
}
else{
answers[i]=2;
noPick="false";
break;
}
}
}
if(noPick=="true")
answers[i]=0;
control=control+opciones;
}
return answers;
}
It works great but while looking at my favorite browsers (FireFox, Chrome) error log it says:
TypeError: rbuttons[control + j] is undefined
Any clue on how to deal with this matter?
This probably means that control + j is greater than or equal to the length of the array rbuttons. There's no such array element as rbuttons[control + j].
You should learn how to use the JavaScript debugger in your favorite browsers! Debuggers are great. They let you watch this code run, line by line, as fast or as slow as you want, and watch how the value of control changes as you go.
You’ll watch it, and you’ll think “Oh! That line of code is wrong!”
You're looping through rbuttons.length times, but in each loop you're adding 2 to control. Using control to index your array, you're going to run past the end.
Does the index specified by control + j exist in the array? i.e: If that evaluates to 4, is there at least 5 items in the array?
Also, you should be using var i, var j, etc inside your for loop. Without it your variables are leaking into the scope this code is executed in (most likely the global scope, and that's not good) :)

Categories

Resources