How to change the innerHTML of the char js - javascript

I want to make a Hangman game so I can learn JavaScript, I don't know how to change the innerHTML
of the char I made in js. So when I know if the string includes the guess then i want to make the line which represents the correct guess to transform into a charater and make it apear but when i run the code it turns the last of the lines into the correct guess and makes it disapear when there's a new guess and transforms the line into second correct guess. And doesn't reconizez 'o'(the last character that is in the string)
I would like to apologize if I made grammer mistakes.
//defineing the word
var a = 'hello';
// makes the lines
for ( var i=0; i<a.length; i++){
var letter = document.createElement("h3");
letter.className = 'letter'+i;
var j = 2*i+23;
letter.style ="position: absolute;"+"top: 14%;"+"left: "+j+"%;";
letter.innerHTML = "_";
document.body.appendChild(letter);
}
//submit btn gets the input and if it's correct shows it, if it isn't correct than puts into a wrong words
function submt(a,letter){
var inpt = document.getElementById('input');
if (a.includes(inpt.value)){
letter.innerHTML = a[a.indexOf(inpt.value)];
}else {
console.log('wrong')
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hangman</title>
<link rel="stylesheet" href="style.css">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Yanone+Kaffeesatz:wght#500&display=swap" rel="stylesheet">
</head>
<body>
<p class='letter'>Write the letter in here:</p>
<p class='bad'> the wrong letters:</p>
<p class='word'>the word:</p>
<input type="text" class="input" id="input">
<button class="sub" id='submit' onclick="submt(a,letter)">submit</button>
<script src="script.js"></script>
</body>
</html>

You were resetting the letter variable to the last h3 element. You needed a array for each of the slots.
//defineing the word
var a = 'hello';
// makes the lines
var letters = []; // this array store the h3 elements
for ( var i=0; i<a.length; i++){
var letter = document.createElement("h3");
letter.className = 'letter'+i;
var j = 2*i+23;
letter.style ="position: absolute;"+"top: 14%;"+"left: "+j+"%;";
letter.innerHTML = "_";
document.body.appendChild(letter);
letters.push(letter); // add element to array
}
//submit btn gets the input and if it's correct shows it, if it isn't correct than puts into a wrong words
function submt(a,letter){
var inpt = document.getElementById('input');
if (a.includes(inpt.value)){
var l = 0, result = [];
while (l<a.split('').length) {
if (a.split('')[l] == inpt.value) { // a split('') turns the word into an array so it is easier to search
result.push(l); // this store the position of the correct letter in the word
}
l++;
}
var l = 0;
while (l<result.length) {
letters[result[l]].innerHTML = a.split('')[result[l]]; // change the h3 elements content to the correct letter using the result array.
l++;
}
}else {
console.log('wrong')
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hangman</title>
<link rel="stylesheet" href="style.css">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Yanone+Kaffeesatz:wght#500&display=swap" rel="stylesheet">
</head>
<body>
<p class='letter'>Write the letter in here:</p>
<p class='bad'> the wrong letters:</p>
<p class='word'>the word:</p>
<input type="text" class="input" id="input">
<button class="sub" id='submit' onclick="submt(a,letter)">submit</button>
<script src="script.js"></script>
</body>
</html>

You are currently accessing always the last dash created.
Thats because createElement will create a h3 element for each char in the word.
for ( var i=0; i<a.length; i++){
var letter = document.createElement("h3");
...
}
After the loop the variable var letter will contain the last h3 element created. You defined letter inside a for loop but access it inside a method.
It works in javascript but is a bit unexpected to see.
I assume you are not yet familiar with scopes. That is okay for now but maybe also something you want to read about for future progress.
https://www.w3schools.com/js/js_scope.asp
A solution close to your solution, but which uses an array to save all h3 elements.
Note that I also removed the parameters of submt() because you did not use them.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hangman</title>
<link rel="stylesheet" href="style.css">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Yanone+Kaffeesatz:wght#500&display=swap" rel="stylesheet">
</head>
<body>
<p class='letter'>Write the letter in here:</p>
<p class='bad'> the wrong letters:</p>
<p class='word'>the word:</p>
<input type="text" class="input" id="input">
<button class="sub" id='submit' onclick="submt()">submit</button>
<script src="script.js"></script>
</body>
</html>
//defineing the word
var a = 'hello';
// makes the lines
var letters = []
for ( var i=0; i<a.length; i++){
var letter = document.createElement("h3");
letter.className = 'letter'+i;
var j = 2*i+23;
letter.style ="position: absolute;"+"top: 14%;"+"left: "+j+"%;";
letter.innerHTML = "_";
document.body.appendChild(letter);
letters.push(letter)
}
function submt(){
var inpt = document.getElementById('input');
if (a.includes(inpt.value)){
var index = a.indexOf(inpt.value)
letters[index].innerHTML = a[index];
}else {
console.log('wrong')
}
}

Related

Why doesn't my element update during the else part but during the if part?

I'm making a program where it has a collection of calculators, and for some reason when I try to change the innerhtml of a certain text it only changes it during the if statement and not during the else part.
function Palindrome() {
//Fix not changing to processing when doing new palindrome.
var Division = 0;
var input = document.getElementById("PalindromeInput").value;
var GiveAnswer = document.getElementById("PalindromeAnswer");
var Answer = String(input);
while (0 < 1) {
if (Answer == Answer.split("").reverse().join("")) {
GiveAnswer.innerHTML = `That is a palindrome of the ${Division}th Division.`;
break
} else {
GiveAnswer.innerHTML = `Processing...`;
Division = Division + 1;
Answer = String(parseInt(String(Answer)) + parseInt(Answer.split("").reverse().join("")));
};
};
};
https://replit.com/#ButterDoesFly/Arcane-Calculators#index.html
I'm not sure but I guess the reason for this is that the function never goes to the else part because it gets break every time. Remember that .reverse() reverses the array in place so the if statement will always be true. Try to add different variable for the reversed answer.
function Palindrome() {
//Fix not changing to processing when doing new palindrome.
var Division = 0;
var input = document.getElementById("PalindromeInput").value;
var GiveAnswer = document.getElementById("PalindromeAnswer");
var Answer = String(input);
GiveAnswer.innerHTML = `Processing...`;
setTimeout(()=>{
while (0 < 1) {
if (Answer == Answer.split("").reverse().join("")) {
GiveAnswer.innerHTML = `That is a palindrome of the ${Division}th Division.`;
break
} else {
Division = Division + 1;
Answer = String(parseInt(String(Answer)) + parseInt(Answer.split("").reverse().join("")));
};
};
},1000)
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>replit</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<p id="PalindromeAnswer">This will tell you the number its at and then the answer.</p>
<input type="text" id="PalindromeInput" placeholder="What number would you like to enter?">
<br>
<input type="button" onclick="Palindrome()" value="Submit" id="PalindromeButton">
<script src="script.js"></script>
<!--
This script places a badge on your repl's full-browser view back to your repl's cover
page. Try various colors for the theme: dark, light, red, orange, yellow, lime, green,
teal, blue, blurple, magenta, pink!
-->
<script src="https://replit.com/public/js/replit-badge.js" theme="blue" defer></script>
</body>
</html>
result is rendering very fast such that changes are not reflecting in ui..add a timeout so that changes reflect in front end

I am not sure I can access the second html file using one js file, html element is showing as null when it is a button

I have 2 html files connected to one js file. When I try to access a html element in the second html file using js it doesn't work saying that is is null. I did
let elementname = document.getElementById("element") for a element in the second html page then
console.log(elementname) and it says it is null. When I do it for a element in the first html page it says HTMLButtonElement {}
Here is the html for the first Page
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Not Quuuuiiiizzzz</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Not Quuuuiiiizzzz</h1>
<h2>Join a quiz</h2>
<!--Buttons -->
<div style="text-align: center;">
<button id="btnforquiz1" onclick="gotoquiz()"></button>
<button id="btnforquiz2" onclick="gotoquiz1()"></button>
<button id="btnforquiz3" onclick="gotoquiz2()"></button>
</div>
<h2 id="h2">Create a Quuuuiiiizzzz</h2>
<script src="script.js"></script>
</body>
</html>
For the second page
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Not Quuuuiiiizzzz</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body onload="quizLoad()">
<h1 id="question">Hello</h1>
<button id="answer1"></button>
<button id="answer2"></button>
<button id="answer3"></button>
<button id="answer4"></button>
<script src="script.js"></script>
</body>
</html>
And Finally for the js file :
//setting global variables
let btn1 = document.getElementById("btnforquiz1") //getting button with id of btnforquiz1 repeat below
correct = 0
let btn2 = document.getElementById("btnforquiz2")
let btn3 = document.getElementById("btnforquiz3")
let question = document.getElementById("question")
let answer1 = document.getElementById("answer1")
let answer2 = document.getElementById("answer2")
let answer3 = document.getElementById("answer3")
let answer4 = document.getElementById("answer4")
quizNameRel = -1;
cosnole.log(question)
console.log(answer1)
//Quiz Data
Quiz_1 = {
"What is the capital of buffalo":["Idk", "Yes", "No",0],
"What is the smell of poop": ["Stinky"]
};
Quiz_2 = [
"What is wrong with you"
];
Quiz_3 = [
"What is wrong with you #2"
]
let quiz = {
name: ["History Test", "Math Practice", "ELA Practice"],
mappingtoans: [0,1,2],
QA: [Quiz_1, Quiz_2, Quiz_3]
}
//quiz data
//when body loades run showQuizzs function
document.body.onload = showQuizzs()
function showQuizzs() {
//loops throo the vals seeting the text for the btns
for (let i = 0; i < quiz.name.length; i++) {
btn1.textContent = quiz.name[i-2]
btn2.textContent = quiz.name[i-1]
btn3.textContent = quiz.name[i]
}
}
//leads to the showQuizzs
function gotoquiz() {
location.href = "quiz.html"
quizNameRel = quiz.name[0]//I was trying to create a relation so we could knoe which quiz they wnt to do
startQuiz()
}
function gotoquiz1() {
location.href = "quiz.html"
quizNameRel = quiz.name[1]
startQuiz()
}
function gotoquiz2() {
location.href = "quiz.html";
quizNameRel = quiz.name[2];
startQuiz();
}
function answerselect(elements){
whichone = Number(elements.id.slice(-2,-1))
if(Quiz_1[whichone]==Quiz_1[-1]){
correct+=1;
NextQuestion();
}else{
wrong+=1;
}
}
//gets the keys and puts it into an array
function getkeys(dictionary){
tempdict = [];
for(i in dictionary){
tempdict.push(i);
}
return tempdict;
}
function setQuestion() {
let tempdict = getkeys(Quiz_1)
console.log(tempdict, getkeys(Quiz_1));
//question.innerHTML = tempdict;
}
// startQuiz
function startQuiz() {
switch (quizNameRel){
case quiz.name[0]:
//case here
setQuestion()
break
case quiz.name[1]:
//case here
break
case quiz.name[2]:
//case here
break
}
}
//TO DO:
// Set the question
// Set the answer
// Check if correct button
This is happening because at a time you have rendered only one html file. For example if you render index1.html(first file) then your js will look for rendered element from first file only but here index2.html(second file) is not rendered so your js script is unable to find elements of that file that's the reason it shows null.
If you try to render now index2.html rather than index1.html then you will find now elements from index2.html are detected by js script but elements from index1.html are null now.

Input is blank after I update text in mirroring div

I am trying to create a very basic markdown editor. I am using a textarea on the left to type in data, and on the right, I have an entry point div where I'm storing everything I type in as I type it using a "keyup" listener. I have gotten the text to apply a class to make it bold when the code is formatted with * at the beginning and end of a word, but after the DOM is updated with this the next word I try to type in doesn't get added and is in fact showing up as blank when I run it through a debugger.
Here is the JS I have currently...
const html = document.querySelector('#html-area');
const md = document.querySelector('#markdown-area');
html.addEventListener("keyup", function(e) {
md.innerHTML = e.target.value;
const words = md.innerHTML.split(' ');
const len = words.length;
for(let i = 0; i < len; i++) {
// if the first character is * and the last character is * and the length of the current word is greater than or equal to 2 then change that word by adding the ".bold" class to it.
if(words[i][0] === "*" && words[i][words[i].length - 1] === "*" && words[i].length >= 2){
const indexOfWord = md.innerHTML.split(' ').indexOf(words[i]);
const newWord = md.innerHTML.split(' ')[indexOfWord] = ` <span class="bold">${md.innerHTML.split(' ')[indexOfWord]}</span> `;
const before = md.innerHTML.split(' ').slice(0, indexOfWord).join();
md.innerHTML = before + newWord;
break;
}
}
});
And here is my HTML...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" href="./css/index.css" />
<title>MarkDown</title>
</head>
<body>
<!-- HTML -->
<div id="app">
<div id="html-container">
<h2>HTML</h2>
<section>
<label for="html-area"></label>
<textarea
name="html-area"
placeholder="type html here..."
id="html-area"
></textarea>
</section>
</div>
<!-- Markdown -->
<section id="markdown-container">
<h2>MarkDown</h2>
<div>
<div
id="markdown-area"
>Markdown text will show here...</div>
</div>
</section>
</div>
<script src="./index.js"></script>
</body>
</html>
Thanks for any tips or help.
One thing: here
md.innerHTML = before + newWord;
you're cutting the output with the newWord. You need to define some after similar to before, and md.innerHTML = before + newWord + after;.
Although a better solution would be to do: split - map - join. Split the input text into words, map them into either original or bold version, and join back. Something like this:
const html = document.querySelector("#html-area");
const md = document.querySelector("#markdown-area");
const bold = word =>
`<span class="bold">${word.substring(1, word.length - 1)}</span>`;
const boldOrNot = word =>
word.startsWith("*") && word.endsWith("*") && word.length > 2
? bold(word)
: word;
html.addEventListener("keyup", function(e) {
const input = e.target.value;
const output = input.split(" ").map(boldOrNot).join(" ");
md.innerHTML = output;
});
https://codepen.io/anon/pen/jRrxZx

Why am I getting undefined output Javascript?

I keep getting undefined before my output text in JS.
Here is my code.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Learning javascript</title>
</head>
<body>
<p id="arrayString"></p>
<!-- Javascript -->
<script type="text/javascript" src="JS/app2.js"></script>
</body>
</html>
This is my JS
var arrayString;
var myArray=["Ms.Vickies", "Old Dutch", "Lays"];
for (var i=0; i<myArray.length; i++) {
arrayString=arrayString+myArray[i];
}
document.getElementById("arrayString").innerHTML=arrayString;
my output is undefinedMs.VickiesOld DutchLays
In addition why no spaces? I am new to JS but am working my way up. Cannot figure this out.
It's because in your first loop iteration, arrayString is undefined. Set it equal to an empty string instead.
Instead of declaring arrayString like so:
var arrayString;
Initialize it with an empty string:
var arrayString = '';
Because you are initiating a null/undefined variable by doing this: var arrayString;
You can fix it by doing this: var arrayString = "";
Better yet, instead of using a for loop, you can do it like this:
var myArray=["Ms.Vickies", "Old Dutch", "Lays"];
document.getElementById("arrayString").innerHTML = myArray.join(" ");
More info: http://www.w3schools.com/jsref/jsref_join.asp
In code ,you have just declared,not initialized.so,just replace
var arrayString;
with
var arrayString = '';
Hope it helps...Thank you.

Why one requires getElementById and the other doesn't

Why does this work
app.prints(address,list.options[list.selectedIndex].value);
but this doesn't?
app.prints(status,macAddress);
JavaScript
var hey = 5;
var app = {
createList: function () {
for (var i = 0; i < 5; i++) {
list.options[i] = new Option(hey + i, "mac" + i);
}
app.prints(address, list.options[list.selectedIndex].value);
},
prints: function (location, message) {
location.innerHTML = message;
},
manageConnection: function () {
var macAddress = list.options[list.selectedIndex].value;
app.prints(status, macAddress);
}
}
HTML
<!DOCTYPE html>
<!-- Don't panic! All this
code looks intimidating but eventually it will make sense. -->
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript" src="ECMA.js"></script>
<title>My LCD code</title>
</head>
<body onload="app.initialize();">
<p>Welcome to the LCD software</p>
<select id="list" onchange="app.prints
(address,list.options[list.selectedIndex].value);"></select>
<div id="address"></div>
<button id="connect" onclick="app.manageConnection();">Connect</button>
<div id="status">hi</div>
</body>
</html>
The difference is that a global status variable has already been defined by the browser to represent the text in the status bar. And, browsers don't allow a reference to the element to replace it.
To avoid the naming conflict, you can rename the element.
But, you really shouldn't depend on automatic globals for ids. Not all browsers implement the feature, and some only in certain modes.
var list = document.getElementById('list');
var address = document.getElementById('address');
app.prints(address, list.options[list.selectedIndex].value);

Categories