Javascript function stops being recognized - javascript

I'm having a problem with the following code snippet:
<!DOCTYPE html>
<html>
<head>
<title>Hangman</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
<!--
gallows = new Array("--------\n| |\n|\n|\n|\n|\n=====",
"--------\n| O\n|\n|\n|\n|\n=====",
"--------\n| O\n| |\n|\n|\n|\n=====",
"--------\n| O\n| \\|\n|\n|\n|\n=====",
"--------\n| O\n| \\|/\n|\n|\n|\n=====",
"--------\n| O\n| \\|/\n| |\n|\n|\n=====",
"--------\n| O\n| \\|/\n| |\n| /\n|\n=====",
"--------\n| O\n| \\|/\n| |\n| / \\\n|\n=====");
guessChoices = new Array("JavaScript", "Navigator", "LiveConnect", "LiveWire");
guessed = [];
function startAgain()
{
guesses = 0;
max = gallows.length - 1;
//guessed = " ";
len = guessChoices.length - 1;
toGuess = guessChoices[Math.round(len*Math.random())].toUpperCase();
displayHangman();
displayToGuess();
displayGuessed();
}
function stayAway()
{
document.game.elements[3].focus();
alert("Don't mess with this form element!");
}
function displayHangman()
{
document.game.status.value=gallows[guesses];
}
function displayToGuess()
{
pattern = "";
for(i=0;i<toGuess.length;++i)
{
if(guessed.indexOf(toGuess.charAt(i)) != -1)
pattern += (toGuess.charAt(i)+" ");
else pattern += "_ ";
}
document.game.toGuess.value=pattern;
}
function displayGuessed(s)
{
result="";
for(i in s)
{
guess=s[i];
result += guess;
}
document.game.guessed.value=result;
//document.game.guessed.value=guessed;
}
function badGuess(s)
{
if(toGuess.indexOf(s) == -1) return true;
return false;
}
function winner()
{
for(i=0;i<toGuess.length;++i)
{
if(guessed.indexOf(toGuess.charAt(i)) == -1) return false;
}
return true;
}
function guess(s)
{
if(guessed.indexOf(s) == -1) guessed.push(s);
if(badGuess(s)) ++guesses;
displayHangman();
displayToGuess();
displayGuessed(guessed);
if(guesses >= max)
{
alert("You're dead. The word you missed was "+toGuess+".");
startAgain();
}
if(winner())
{
alert("You won!");
startAgain();
}
}
// -->
</script>
</head>
<body>
<h1>Hangman</h1>
<form name="game">
<pre>
<textarea name="status" rows="7" cols="16" onfocus="stayAway();"></textarea>
</pre>
<p>
<input type="text" name="toGuess" onfocus="stayAway();"> Word to guess<br>
<input type="text" name="guessed" onfocus="stayAway();"> Letters guessed so far<br>
</p>
<p>Enter your next guess.</p>
<p>
<input type="text" name="input" size=1 value="">
<input type = "button" value = "guess" onclick = "guess(game.input.value); game.input.value = '';">
</p>
<input type="button" name="restart" value="---- Start Again ----" onclick="startAgain();">
<script type="text/javascript">
<!--
startAgain();
// -->
</script>
</form>
</body>
</html>
After I click the game.guess button, the first time around, I get the expected output... game.input clears and guessed is displayed. However, the second time I click the guess button with a different value, I receive the error:
guess is not a function
| onclick()
| event = click clientX=77, clientY=33
guess(game.input.value) onclick(line 2)
And I honestly can't figure out why. What am I doing wrong?
(I got the bulk of this code from Mastering JavaScript, Premium Edition, by James Jaworski)

The problem is on these lines:
guess=s[i];
result += guess;
This way you are changing the context of guess. If you change this line to
result += s[i];
Your error will go away.
You are conflicting your function with using same name for a variable.
Remember to define your variables using var keyword and avoid such confusion.
1 - use anonymous functions where possible
2 - declare and use local variables
To avoid conflicts.

In your function displayGuessed(), you are setting the variable guess (which is a function) to the the guessed letters.
You can fix this by defining your function's guess variable (making it distinct from the function) using the "var" keyword:
function displayGuessed(s)
{
var guess;
result="";
for(i in s)
{
guess=s[i];
result += guess;
}
document.game.guessed.value=result;
}
Tip: I found this bug easily by using the Firebug plugin for firefox, which lets you step through javascript code line by line, to see where things are going wrong.

Related

Why can't javascript set the value of a HTML form element?

Title says it all, i am setting a value in a variable in a javascript.
I want to set that value as value of the one of the row in my form.
here is the code, this is based on previous similar questions and their accepted answers, but somehow it does not work for me.
<html>
<head>
<script>
var counter = 0;
var limit = 50;
function addInput(divName){
if (counter == limit) {
alert("You have reached the limit of adding " + counter + " inputs");
}
else {
var newdiv = document.createElement('div');
newdiv.innerHTML = "Element " + (counter + 1) + " <input type='text' name='myInputs[]'>";
document.getElementById(divName).appendChild(newdiv);
counter++;
}
}
</script>
</head>
<body>
<form method="POST" align="center">
<script>
var emotion = "";
var raw = Math.random();
var final = Math.ceil(raw * 4);
if (final == 1)
document.getElementById("someid").value = "A";
else if (final == 2)
document.getElementById("someid").value = "B";
else if (final == 3)
document.getElementById("someid").value = "C";
else if (final == 4)
document.getElementById("someid").value = "D";
</script>
<div id="dynamicInput">
Title<br><input type="text" value="" name="myInputs[]" id="someid" disabled>
</div>
<input type="button" value="Add another event" onClick="addInput('dynamicInput');">
<br>
<input type="submit" value="Submit">
</form>
</body>
</html>
I also tried something like:
document.forms[0].myInputs[0].value="Whatever"
inside the script tags, but that also does not work.
Edit_1
I expect some value in the disabled input field, just below the title, but its empty.
Here is the image:
How can I have some value based on a random number generator there?
check the jsfiddle, this is due to how u arrange ur script, you either move ur code below the html, or use onload() event
example
onload="test()"
then you will no need to worry where the js should put
<script>
function test(){
var emotion = "";
var raw = Math.random();
var final = Math.ceil(raw * 4);
if (final == 1)
document.getElementById("someid").value = "A";
else if (final == 2)
document.getElementById("someid").value = "B";
else if (final == 3)
document.getElementById("someid").value = "C";
else if (final == 4)
document.getElementById("someid").value = "D";
}
</script>
https://jsfiddle.net/gw04jhoj/
you can refer to this for more info
Javascript that executes after page load
Your script is running before those HTML elements have been created, and so setting their value will fail, as document.getElementById("someid") doesn't exist yet. You should see this fail in the error console in the browser (F12).
Try moving the script until after you've created the HTML elements in question, or better yet change your script to only execute once the document has loaded.
You should use :
document.getElementById("someid").value="whatever";

inner.html / handlers

as an incoming javascript coder, i'm stuck at a sample exercise...
<script language="JavaScript">
var num1;
var messages;
var answer = document.getElementById("guess").value;
var counter = 0;
answer = Math.floor(1 + Math.random() * 32);
function start() {
var button = document.getElementById("guessButton");
button.addEventListener("click", Myguess, false);
};
function Myguess() {
num1 = document.getElementById("guess").value;
do {
if (num1 == answer) {
messages.innerHTML = "Ahah!"
}
if (num1 < answer) {
messages.innerHTML = "Either you know the secer or you got lucky!";
}
if (num1 > answer) {
messages.innerHTML = "you should be able to do better";
}
}
}
</script>
<body>
<form action="#">
<input id="guessButton" type="button" value="guess">
<input id="inputfield" type="number" value="guess a number 1- 32">
</form>
</body>
this is supposed to print:
number of guesses is 5 or fewer: "either you know the secret or you got lucky"
Or number of guesses is 5 or more:"you should be able to do better"
Or number of guesses in 5 tries : "ahah!"
however it's not printing .../././
Initially there are few syntax errors to correct
do {} without while is not valid javascript.
start() is never called. I'm guessing you intended to use window.onload = start or <body onload="start();">
Your script is executed before the HTML elements it is modifying. If you want to access elements from the DOM you should access them within a function and/or place the script at the bottom of the body tag.
<script language="JavaScript"> is deprecated. I think you mean <script type="text/javascript"> although as that is the default the type is optional.
The messages variable is never assigned
You set text as the value to a number input. I suspect you intended to use placeholder="guess a number 1- 32". Note that placeholder is actually used to provide a hint about expected input. Direct instructions should use a label. This doesn't affect your javascript but is worth considering all the same.
Additionally myGuess() currently checks if the submitted value is less than the answer or more. You need to increment a count value and compare against that.
The below example do what you need
<form action="#">
<label for="inputfield">guess a number 1-32</label>
<input id="guessButton" type="button" value="guess">
<input id="inputfield" type="number">
</form>
<p id="messages"></p>
<script type="text/javascript">
var num1;
var target = 5;
var messages = document.getElementById("messages");
var counter = 0;
var answer = Math.floor(1 + Math.random() * 32);
function start() {
var button = document.getElementById("guessButton");
button.addEventListener("click", Myguess, false);
};
function Myguess() {
num1 = document.getElementById("inputfield").value;
if(num1 == answer) {
if (counter === target) {
messages.innerHTML = "Ahah!"
}
if (counter < target) {
messages.innerHTML = "Either you know the secer or you got lucky!";
}
if (counter > target) {
messages.innerHTML = "you should be able to do better";
}
} else {
counter++;
messages.innerHTML = "Keep trying";
}
}
window.onload = start;
</script>
<script language="JavaScript">
var num1;
var messages; // should be initialized inside start because at this moment it doen't exist
var answer;
var counter = 0;
answer = Math.floor(1 + Math.random() * 32);
window.addEventListener("load", start); // on loading the page call start;
function start() {
messages = document.getElementById("message"); // this should be something
var button = document.getElementById("guessButton");
button.addEventListener("click", Myguess, false);
};
function Myguess() {
num1 = document.getElementById("inputfield").value; // the id is "inputfield" not "guess"
if (num1 == answer) {
messages.innerHTML = "Ahah!"
}
// else if to stop checking again (if is correct but not the best)
else if (num1 < answer) {
messages.textContent = "Either you know the secer or you got lucky!"; //textContent is better than innerHTML
}
// same here
else if (num1 > answer) {
messages.innerHTML = "you should be able to do better";
}
}
</script>
<body>
<form action="#">
<input id="guessButton" type="button" value="guess">
<input id="inputfield" type="number" value="guess a number 1- 32">
</form>
<div id="message"></div>
</body>
Note: you was using do-while incorrectly (you was messing the while part). Anyway, do-while or any other loop will just loop forever if the answer is not correct because you are not letting the user to re-enter a number. What you need is to check whether the number is correct or not whenevr the user click the button (that parts you had it correct because you used the event listener).
What your code was doing (or supposed to be doing) is check if a user clicks the button and then loop if his answer was incorrect untill the answer is is correct (which is not going to happen because you never give the user another chance to enter a number again. He will get a chance after the function execution is finished. And because of the loop it will never be finished). It was never going to work because the loop waits for the user to enter another number (a correct one) to exit and the user is waiting for the loop to end to enter another number (see the paradox).
What it should do is to wait for the user to enter a number, check that number, prints the message accordingly for that number and then give the user to enter another number. (It is a loop (cycle) already so why need another loop)
The code you need is this:
<body>
<form id="form">
<input id="guessButton" type="submit" value="guess">
<input id="inputfield" type="number" placeholder="guess a number 1-32">
</form>
<div id="messages"></div>
<span id="counter"></span> tries
</body>
<script language="JavaScript">
document.getElementById('form').onsubmit = function() {
return Myguess();
};
var num1;
var messages = document.getElementById("messages");
var counterDiv = document.getElementById("counter");
counterDiv.innerHTML = 0;
var counter = 0;
answer = Math.floor(1 + Math.random() * 32);
function Myguess() {
num1 = document.getElementById("inputfield").value;
if (num1 == answer) {
messages.innerHTML = "Ahah!"
}
if (num1 < answer) {
messages.innerHTML = "Either you know the secer or you got lucky!";
}
if (num1 > answer) {
messages.innerHTML = "you should be able to do better";
}
counter++;
counterDiv.innerHTML = counter;
return false;
}
</script>
You can test it in this JSFiddle.
The function Myguess() is called when the form is submitted. There was no div messages missing in your code, so I added it. I also added the counter span which shows how many tries the player has had. Also the message "guess a number 1-32" is better added as placeholder. I hope that was helpful !

A function that is not a function?

I'm still new to coding and I'm trying to make a cookie clicker type game. I get
upgradecursor is not a function
when I run it on Chrome. I don't really understand the problem as I have a function called upgradecursor.
Pls help! :(
<!DOCTYPE html>
<html>
<head>
<title> Test </title>
<script>
//List of variables
var cookie = 0;
var cursor = 1;
var cursorupgradecost = 10;
function addcookie(){
var textField = document.getElementById( "textField" );
var currentValue = parseInt(textField.value);
cookie = cookie + cursor;
// Add one
currentValue = currentValue + cursor;
// Put it back with the new +1'd value
textField.value = currentValue;}
function upgradecursor(){
var textField = document.getElementById( "textField" );
var currentValue = parseInt(textField.value);
cookie = cookie - cursorupgradecost;
// Minus one
currentValue = currentValue - cursorupgradecost;
// Put it back with the new -10'd value
textField.value = currentValue;
//change the cost of the upgrade
cursorupgradecost = cursorupgradecost * 1.5;
//Upgrade the cursor
cursor = cursor + 1;
}
</script>
</head>
<body>
<script>
if (cursorupgradecost > cookie){
upgradecursor = false;}
else{
upgradecursor = true;}
</script>
<button type ="button" onClick = "upgradecursor()"/>Upgrade Cursor </button>
<input type="text" value="0" disabled name="lvl">
<br>
<button type="button" onClick="addcookie()"/>Add Cookie</button>
<input type="button" value="Cookies" disabled name="clicker">
<input type="text" value="0" id="textField" readonly/>
</body>
</html>
You are overwriting upgradecursor with a global variable after you include the JavaScript.
<script>
if (cursorupgradecost > cookie) {
upgradecursor = false;
} else {
upgradecursor = true;
}
</script>
This is the offending code. You need to rename this variable to something else to avoid overwriting the function.
Additionally, you should definitely avoid declaring global variables like this and look at making your code more encapsulated/modular.
--
Update based on your objective: If you want to only upgrade the cursor given a certain use case, then it might be useful to have a specific click handler that will run this check inside itself before calling upgradecursor. For example: -
function onCursorClick() {
if (cursorCost > cookie) {
// do something
} else {
upgradeCursor();
}
}
Notice how I have used camel casing to declare my functions and variables? Make sure you update your variable declarations to match my casing. This is common practice. You can read more on coding conventions here: W3Schools JavaScript Style Guide
I'd like to point out listeners should be attached via JavaScript (see DOM Event Listeners), but make sure you update the click handler to match our update, like so: -
<button type="button" onClick="onCursorClick()"/>Upgrade Cursor</button>
You have this:
if (cursorupgradecost > cookie){
upgradecursor = false;}
else{
upgradecursor = true;}
So while you started out by defining upgradecursor as a function, you overwrote it with a boolean before you ever called it.
The problem is here:
<script>
if (cursorupgradecost > cookie){
upgradecursor = false;}
else{
upgradecursor = true;}
</script>
What on earth is that supposed to even do?
Remove it and it should work.

Number Guessing Game using while loop

In this project, I need to set a maximum of 10 guesses, an indication of what number is being guessed and keep those results on the screen at the end of each game without overwrite the previous guesses.
Each set of guess output needs to be numbered to indicate how many guesses have been made. For the output, I need to use innerHTML. The user will guess a number from 1 to 999. I have to use while loop.
So far this is the code where I'm working and I have some errors and it's not working. Can anybody put me in the right direction to finish this code?
The errors that I found when I inspect the document are checkGuess() function and an anonymous function with a message "Cannot read property 'value' of null"
<script type="text/javascript">
var randomNumber = Math.floor(Math.random() * 100) + 1;
var guesses = document.getElementById("guesses");
var lastResult = document.getElementById("lastResult");
var lowOrHi = document.getElementById("lowOrHi");
var guessSubmit = document.getElementById("guessSubmit");
var guessField = document.getElementById("guessField");
var guessCount = 1;
function checkGuess() {
var userGuess = Number(guessField.value);
guesses.innerHTML += userGuess + "";
}
while (guessCount == 10) {
lastResult.innerHTML = "!!!GAME OVER!!!";
disableForm();
} else {
if (userGuess == randomNumber) {
lastResult.innerHTML = "Congratulations! You got it right!";
lowOrHi.innerHTML = "";
disableForm();
} else {
lastResult.innerHTML = "Wrong!";
if (userGuess < randomNumber) {
lowOrHi.innerHTML = "Your guess is too low!";
} else if (userGuess > randomNumber) {
lowOrHi.innerHTML = "Your guess is too high!";
}
}
guessCount++;
guessField.value = "";
}
}
function disableForm() {
var wholeForm = document.querySelector(".form"); // grab a reference to the whole form (the contents of the div with class form)
wholeForm.style.opacity = 0.5; // change the opacity of the form to 0.5
guessField.setAttribute("disabled", "disabled");
guessSubmit.setAttribute("disabled", "disabled"); // disable the form field and submit button so they can no longer be used
}
guessSubmit.onclick = checkGuess;
</script>
</head>
<body>
<h1>Number guessing game</h1>
<p id="guesses"></p>
<p id="lastResult"></p>
<p id="lowOrHi"></p>
<div class="form">
<label for="guessField">Enter your next guess: </label>
<input type="text" id="guessField">
<button id="guessSubmit">Enter Guess</button>
</div>
<p></p>
</body>
</html>
Your program is all wrong and is actually doing nothing
the only thing that actually executes is everything outside your functions,
and those are being called only when the page is loaded for first time
in order to execute your CheckGuess you need to actually call it :
<button id="guessSubmit" onclick="checkGuess() ">Enter Guess</button>
but everything else that is actually outside of your functions are only executed when the page is loading
also you have a while--else statement, that's not even possible
then again... it is outside a function so it is useless
You need to put everything on one single statement
YOU DO NOT NEED A WHILE
once you write something down on the page it will stay there until it reloads
if you write a while like that you will just loop your code endless.
this code and logic is so wrong in so many ways i will sent you a functional code :
<script type="text/javascript">
var guesscount =0;
var randomNumber = Math.floor(Math.random() * 100) + 1;
function checkGuess()
{
guesscount = guesscount +1;
var userGuess = document.getElementById("guessField").value;
document.getElementById('guesses').innerHTML += Number(userGuess)+ '<br>';
CheckResults();
}
function CheckResults()
{
//add here your logics if the number is wrong
if ( guesscount>= 10)
{
document.getElementById("guessField").disabled = true;
document.getElementById("guessSubmit").setAttribute('disabled', 'disabled');
document.getElementById('guesses').innerHTML += 'game Over !';
}
}
</script>
</head>
<body>
<h1>Number guessing game</h1>
<label id="guesses"></label>
<label id="lastResult"></label>
<label id="lowOrHi"></label>
<div class="form">
<label for="guessField">Enter your next guess: </label>
<input type="text" id="guessField">
<button id="guessSubmit" onclick="checkGuess() ">Enter Guess</button>
</div>
<p></p>
</body>
</html>

How do I compare the value of an element returned by getElementsByName to a string?

I'm making a quiz with a text input. This is what I have so far:
<html>
<head>
<script type="text/javascript">
function check() {
var s1 = document.getElementsByName('s1');
if(s1 == 'ō') {
document.getElementById("as1").innerHTML = 'Correct';
} else {
document.getElementById("as1").innerHTML = 'Incorrect';
}
var s2 = document.getElementsByName('s2');
if(s2 == 's') {
document.getElementById("as2").innerHTML = 'Correct';
} else {
document.getElementById("as2").innerHTML = 'Incorrect';
}
//(...etc...)
var p3 = document.getElementsByName('p3');
if(p3 == 'nt') {
document.getElementById("ap3").innerHTML = 'Correct';
} else {
document.getElementById("ap3").innerHTML = 'Incorrect';
}
}
</script>
</head>
<body>
1st sing<input type="text" name="s1"> <div id="as1"><br>
2nd sing<input type="text" name="s2"> <div id="as2"><br>
<!-- ...etc... -->
3rd pl<input type="text" name="p3"> <div id="ap3"><br>
<button onclick='check()'>Check Answers</button>
</body>
</html>
Every time I check answers it always says Incorrect and only shows the first question. I also need a way to clear the text fields after I check the answers. One of the answers has a macro. Thanks in advance.
The method getElementsByName returns a NodeList, you can't really compare that against a string. If you have only one element with such name, you need to grab the first element from that list using such code instead:
var s1 = document.getElementsByName('s1')[0].value;
To make it more flexible and elegant plus avoid error when you have typo in a name, first add such function:
function SetStatus(sName, sCorrect, sPlaceholder) {
var elements = document.getElementsByName(sName);
if (elements.length == 1) {
var placeholder = document.getElementById(sPlaceholder);
if (placeholder) {
var value = elements[0].value;
placeholder.innerHTML = (value === sCorrect) ? "Correct" : "Incorrect";
} else {
//uncomment below line to show debug info
//alert("placeholder " + sPlaceholder+ " does not exist");
}
} else {
//uncomment below line to show debug info
//alert("element named " + sName + " does not exist or exists more than once");
}
}
Then your code will become:
SetStatus('s1', 'ō', 'as1');
SetStatus('s2', 's', 'as2');
//...
document.getElementsByName('s1') is an array you should use document.getElementsByName('s1')[0] to get certain element(first in this case)

Categories