JavaScript - while loop - javascript

I am having trouble displaying images using a while loop using a function showCards(7) to output the HTML to display the images. I believe my problem lies somewhere within the JS function but I can't seem to be able to figure it out.
This assignment is to create a black jack game although this first part should only display 7 cards.
Below is the HTML and JS:
<table border=0 style='margin:auto'>
<tr>
<td>
<form>
<input type="BUTTON" onClick="Javascript:alert('Dummy Link')" value="Deal > > >">
</form>
</td>
<script type="text/javascript">showCards(7)</script>
<td>
<form>
<input type="BUTTON" onClick="Javascript:alert('Dummy Link')" value="< < < Hit Me">
</form>
</td>
</tr>
</table>
function showCards(7) {
while (true) {
document.writeln("< IMG src='http://www.college1.com/images/cards/gbCard52.gif' width=30 height=30 >")
count = count + 1
}
}

The problem is with your truthy in the while() loop. You should modify it to use a for() loop as follows:
function showCards( arg )
{
for(var i = 0; i < arg; i++)
{
document.writeln("< IMG src='http://www.college1.com/images/cards/gbCard52.gif' width=30 height=30 >");
}
}
Notice that the showCards() function now accepts an argument, which should be the number of cards to be added.

You have made an infinite loop, so the code will just keep writing out image tags until the browser stops the script for taking too long to run.
Lets start with the function declaration. You have used the number 7 where you would use a parameter name:
function showCards(cardCount) {
You use a counter inside the loop, which is good, but you should initialise the counter before the loop:
var count = 0;
You should make the loop run as long as there are more images to write out:
while (count < cardCount) {
So:
function showCards(cardCount) {
var count = 0;
while (count < cardCount) {
document.writeln("< IMG src='http://www.college1.com/images/cards/gbCard52.gif' width=30 height=30 >");
count = count + 1;
}
}
You can also use a for loop to do the same thing:
function showCards(cardCount) {
for (var count = 0; count < cardCount; count++) {
document.writeln("< IMG src='http://www.college1.com/images/cards/gbCard52.gif' width=30 height=30 >");
}
}

Related

Issue with Revealing Individual Images & Ending Loop

Since my last question, I've decided to reveal images individually. However, now I'm having an issue with the sequence. With what I've written so far, it seems that my second needed image (stack2.PNG) appears before the first (stack1.PNG). Also, I'm not too sure how to go about ending the function after the final image (stack3.PNG).
Here's what I have so far:
<body>
<input type=button value="Produce Stipends" onclick="nextStack()"/>
<img id="stipends" src="nostack.PNG">
</body>
<script>
var stipends = document.getElementById("stipends");
var stack = ["stack1.PNG", "stack2.PNG", "stack3.PNG"];
var currentStack = 0;
stack.forEach(function(src) {
new Image().src = src;
});
function nextStack() {
currentStack++;
currentStack > 2 && (currentStack = 0);
stipends.src = stack[currentStack];
}
</script>
Also, if it's not too much to ask, how would I go about changing the name of the button once the sequence is over and linking to another page.
Thanks in advance!
Run the below code if you want to output a single index of the stack array on each click.
EDIT: Included comments in code.
var stipends = document.getElementById("stipends");
var stack = ["stack1.PNG", "stack2.PNG", "stack3.PNG"];
//currentStack = 0 starts the index at 0
//we will use this to iterate over the array in sequential order starting with the first item
var currentStack = 0;
function nextStack() {
//declare array length as a var
var len = stack.length;
//on click, check if currentStack value is less than len
if(currentStack < len){
//console log the item in the stack array that has a matching index
console.log(stack[currentStack]);
//apply the same output as image source
stipends.src = stack[currentStack];
//continue adding to the currentStack for the next loop until finished
currentStack++;
}
}
<input type=button value="Produce Stipends" onclick="nextStack()" />
<img id="stipends" src="nostack.PNG">
Is this what you're trying to do?
var stipends = document.getElementById("stipends");
var stack = ["stack1.PNG", "stack2.PNG", "stack3.PNG"];
var currentStack = 0;
function nextStack() {
currentStack++;
stipends.src = stack[currentStack];
if (currentStack > stack.length) {
currentStack = 0;
}
}
<input type="button" value="Produce Stipends" onclick="nextStack()"/>
<img id="stipends" src="nostack.PNG">

Onclick action: two functions; only first working. Quite desperate

This is my html code:
<td width="15%" align="center"><input name="submit" type="submit" class="button"
value="Basic" tabindex="13"
onclick="return submit_Click('bxbas','bxsht');" /></td>
And this is my javascript code:
<script type="text/javascript">
function submit_Click(aclass,bclass) {
var elementsa = document.getElementsByClassName(aclass);
for(i in elementsa)
{
elementsa[i].style.display = "block";
}
var elementsb = document.getElementsByClassName(bclass);
for(j in elementsb)
{
elementsb[j].style.display = "none";
}
}
</script>
Unfortunately this is not working. Apparently, only the first part of the function is working, the one that makes the first class (aclass) to be shown. The second one remains visible.
Thank you
Don't use For.. In in this case. If you Console.Log your elementsa you'll see that the last element is a not a number, so it breaks your elementsa[i]. Using "for" solves the problem:
function submit_Click(aclass, bclass) {
var elementsa = document.getElementsByClassName(aclass);
for (i=0; i < elementsa.length; i++) {
elementsa[i].style.display = "block";
}
var elementsb = document.getElementsByClassName(bclass);
for (j=0; j < elementsb.length; j++) {
elementsb[j].style.display = "none";
}
}

Print from JavaScript function to HTML without document.write()

I searched everywhere on here on an alternative on printing to HTML from a JavaScript function to HTML without using document.write() but document.getElementById() doesn't seem to work and I'm really not sure how to go about doing this.
I have this so far
JavaScript
function trials() {
while (num_trials > 0) {
for (var i = 0; i < random.length; i++) {
document.write(random[i]);
}
}
}
Where "random" is an array of letters
HTML
<div id ="container">
<center>
<i>**TRIALS HERE**</i><br><br>
<font size="8">
<script>trials();</script><br><br>
</font>
</center>
</div>
I'm also looking for a way to hide each letter after each iteration of the for-loop so that it doesn't just print as a long string of letters.
Basic idea is to use an interval to loop through the array so there is a delay. You want to set the text with innerHTML or textContent.
(function() {
var outputElem = document.getElementById("outputSpot"), //where to output the letter on the screen
current = 0, //start index in the array
randomChars = ["W","E","L","C","O","M","E","!"], //characters to show
timer = window.setInterval( //this is how we will loop with an interval
function () {
var letter = randomChars[current]; //get next letter
if (letter) { //if there is no letter, it will be undefined and we will be done
outputElem.innerHTML = letter; //show the letter to the user
current++; //update the index
} else {
window.clearInterval(timer); //cancel the timer since we ran out of things to display
}
}
,1000); //number of seconds to wait between iterations
}());
<span id="outputSpot">Hello!</span>
Javascript
I would try setting the div to a variable:
var div = $('#container');
function trials() {
while (num_trials > 0) {
for (var i = 0; i < random.length; i++) {
div.appendTo(random[i]);
}
}
HTML
Then maybe hiding the container div (style='display:none;') would prevent the numbers printing out, but still accessible:
<div>
<center>
<i>**TRIALS HERE**</i><br><br>
<font size="8">
<script>trials();</script>
<div id="container" style="display:none;"></div><br><br>
</font>
</center>
</div>
It may be very useful for you to use JQuery.
function trials() {
while (num_trials > 0) {
for (var i = 0; i < random.length; i++) {
$('#iToWrite').html( $('#iToWrite').html() + random[i]);
}
}
}
<div id ="container">
<center>
<i id='iToWrite'>**TRIALS HERE**</i><br><br>
<font size="8">
<script>trials();</script><br><br>
</font>
</center>
</div>

Not able to push data into array

I am trying to get to the logic of the Tic Tac Toe game which I almost have made a logic, but I am stuck while pushing the Data to the array. Here is a fiddle that I have created.
http://jsfiddle.net/afzaal_ahmad_zeeshan/6bgjp/1/
Let me explain the whole thing to you!
I am trying to use the 9 td of the table as the 8 rows of the possible win. For that I have given some of the tds a className depending on their location in the table.
The HTML is simple
<div class="vicvacvoe">
<table>
<tr>
<td class="line1 line4 line7"></td>
<td class="line1 line5"></td>
<td class="line1 line6 line8"></td>
</tr>
<tr>
<td class="line2 line4"></td>
<td class="line2 line5 line7 line8"></td>
<td class="line2 line6"></td>
</tr>
<tr>
<td class="line3 line4 line8"></td>
<td class="line3 line5"></td>
<td class="line3 line6 line7"></td>
</tr>
</table>
</div>
Just a simple table with 9 tds, the CSS is not relative to this so leave it I guess.
jQuery for this also simple one. But I am not able to push the data to the Array.
var vic = $('.vicvacvoe table tr td');
var player = 1;
var tick = '✓';
var cross = 'X';
var user1 = [];
var user2 = [];
vic.click(function () {
var className = $(this).attr('class');
if (className != 'dead') {
// A new board place to write on...
// Now do the processes here...
if (player == 1) {
// First player!
var cArray = className.split(' ');
for (i = 0; i < cArray.length; i++) {
for (j = 0; j < user1.length; j++) {
// check for each class
if (user1[j] != cArray[i]) {
user1.push(cArray[i]);
}
}
}
} else {
/* code for second player, the same */
}
$(this).text('Works!');
$(this).attr('class', 'dead');
}
});
This is the entire jQuery script. Actually when I run the code, it really does go to the end of the stack (to the class attribute change script) and it locks the td for further process and it write Works! in the td too. But I am not able to get the classNames inside the Array for that user. I want to save the line number for each user and then check whether he has 3 spots filled or not. I need help with the Array part.
Thanks!
I prefer simplicity so you could use indexOf to check whether the class is already in the users' array like so:
if (player == 1) {
// First player!
var cArray = className.split(' ');
for (i = 0; i < cArray.length; i++) {
if(user1.indexOf(cArray[i]) == -1) {
user1.push(cArray[i]);
} else {
// css class is already in the array
}
}
}
Your issue is here:
for (j = 0; j < user1.length; j++) {
The only place you add to the user1 array is within this loop. Now the array is initially empty, so clearly this loop will never iterate as user1.length is always 0.
I think your intent with this bit of code was to check if the value was already in the array in which case I suggest using $.inArray.

Javascript increment variable to update table cells onclick

I have a page where the user inputs a color and I call the onClick method to change the color of the individual cells of the table. However, when I click any cell, only the last cell (cell3 in this case) will change color. What am I doing wrong?
I get the error:
Message: 'document.getElementById(...)' is null or not an object
Line: 24
Char: 4
Code: 0
My code is:
<html>
<body>
<input type='text' id='userInput' value='yellow' />
<table border="1">
<tr>
<td id="1">cell1
</td>
</tr>
<tr>
<td id="2">cell2
</td>
</tr>
<tr>
<td id="3">cell3
</td>
</tr>
</table>
<script type="text/javascript">
for(var i = 1; i <= 3; i++){
document.getElementById(i).onclick = function(){
var newColor = document.getElementById('userInput').value;
document.getElementById(i).style.backgroundColor = newColor;
}
}
</script>
</body>
</html>
Change your HTML to this: An ID must start with an an alpha character. It is not valid to start with a number.
<table border="1">
<tr>
<td id="td1">cell1
</td>
</tr>
<tr>
<td id="td2">cell2
</td>
</tr>
<tr>
<td id="td3">cell3
</td>
</tr>
</table>
This is a very common Javascript issue: All the code shares the value of i which is 3 at the end of the loop. You can solve it by using another helper function like this:
function changeIt(i) {
// This inner function now has its own private copy of 'i'
return function() {
var newColor = document.getElementById('userInput').value;
document.getElementById("td" + i).style.backgroundColor = newColor;
}
}
for(var i = 1; i <= 3; i++){
document.getElementById(i).onclick = changeIt(i);
}
It can also be written using an anonymous function, but those are harder to read.
First of all, your for loop is wrong. Try:
for(var i = 1; i <= 3; i++) {
//code
}
Second, instead of retrieving the element each time in your loop, you could use this:
this.style.backgroundColor = document.getElementById('userInput').value;
Jeremy's answer is close but there is still a problem in that changeIt is not being called until the element is clicked, by which time the value of i is still three. Using Jeremy's update to the HTML the correct script can be written as...
function createChangeColorHandler(n) {
return function() {
var newColor = document.getElementById('userInput').value;
document.getElementById("td" + n).style.backgroundColor = newColor;
}
}
for(var i = 1; i <= 3; i++) {
// We pass i to the function createChangeColorHandler by value
// at the time of this pass of the loop rather than referencing
// the variable directly after the loop has finished
document.getElementById(i).onclick = createChangeColorHandler(i);
}
As an anonymous function...
for(var i = 1; i <= 3; i++) {
// We pass i to the function createChangeColorHandler by value
// at the time of this pass of the loop rather than referencing
// the variable directly after the loop has finished
document.getElementById(i).onclick = (function(n) {
return function() {
var newColor = document.getElementById('userInput').value;
document.getElementById("td" + n).style.backgroundColor = newColor;
}
})(i);
}
EDIT Jeremy's answer is now correct

Categories

Resources