try to loop through objet & array by pressing button and show every object inside the DOM but it's just show the last objet once i press the button
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn">press</button>
<h1 id="name">name </h1>
<h1 id="age">age</h1>
<script >
const info =[{name : "john", age :"20"},{name : "bob", age :"25"},{name : "wil", age :"30"}]
const btn = document.getElementById('btn')
const name1 = document.getElementById('name')
const age = document.getElementById('age')
btn.addEventListener('click', show)
function show(){
for( i = 0; i < info.length; i++){
name1.innerHTML = info[i].name
age.innerHTML = info[i].age
}
console.log(info);
}
</script>
</body>
</html>
Just look at your code here.
for( i = 0; i < info.length; i++){
name1.innerHTML = info[i].name
age.innerHTML = info[i].age
}
When first time loops runs (for index 0), it stores the value (john and 20) in the html h1 tags.
<h1 id="name">name </h1>
<h1 id="age">age</h1>
And now when the loop run for index 1, then (bob and 25) is storing in the same h1 tags. So, previous values vanished. So in this way, the loop keeps running until the last index. So, it is showing only the last values of the array.
There is a solution that you can do. I have modified your code.
for( i = 0; i < info.length; i++){
if (i = 0){
name1.innerHTML = info[i].name
age.innerHTML = info[i].age
}
else{
name1.innerHTML += info[i].name
age.innerHTML += info[i].age
}
}
In this way, all the names and ages will be show in the h1 tags. This is just for basic understanding that where you are doing mistake.
If you want to show each name and age pair on different h1 tags. You can use Nodes. You create h1 element in the Javascript, and then put text inside the h1 and then use appendChild to place it as a last child in any div you wanted to place or you can use insertBefore to place it as the first child.
You can see the Link of W3Schools mentioned below to understand how element nodes are created and append in the html.
https://www.w3schools.com/jsref/met_node_appendchild.asp
You can create an index variable and store the current index and then get the element at that particular index and then increment it at the end. This is how you can get one by one name and age till last.
const info = [{
name: "john",
age: "20"
}, {
name: "bob",
age: "25"
}, {
name: "wil",
age: "30"
}]
const btn = document.getElementById('btn')
const name1 = document.getElementById('name')
const age = document.getElementById('age')
btn.addEventListener('click', show)
let index = 0;
function show() {
if (index < info.length) {
name1.textContent = info[index].name;
age.textContent = info[index].age;
index++;
}
}
<button id="btn">press</button>
<h1 id="name">name </h1>
<h1 id="age">age</h1>
Related
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.
it was a long time ago that I didn’t program in javascript so I decided to make a project of a "bookcase" to manage read books and that I want to read more I have difficulty with how to separate the elements to personalize the style because it selects all the results of the api in one just div.
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="script.js"></script>
<link rel="stylesheet" href="./css/bookcase.css">
<title>project</title>
</head>
<body>
<div id="content">
</div>
<script src="https://www.googleapis.com/books/v1/volumes?q=clean+code&callback=handleResponse></script>
</body>
</html>
js
function handleResponse(response) {
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
var book = document.getElementById('content')
book.innerHTML += "<br>" + '<img src=' + response.items[i].volumeInfo.imageLinks.thumbnail + '>';
book..innerHTML += "<br>" + item.volumeInfo.title;
book..innerHTML += "<br>" + item.volumeInfo.authors;
Clean answer - you should use document.appendChild(child) instead of innerHTML method.
Also, there are few recently added js methods that can help you operate large JSON objects - map, reduce, filter.
I added example, how you can clean original object to smaller array, and insert items from that array into html-page.
function demo (obj) {
// getting all items from object
const book = Object.keys(obj).map(item => obj['items']).reduce(
(acc,rec, id, array) => {
// getting Cover, Title, Author from each item
let singleBookCover = rec[id].volumeInfo.imageLinks.thumbnail;
let singleBookTitle = rec[id].volumeInfo.title;
let singleBookAuthor = rec[id].volumeInfo.authors[0];
// Creating new array only with Cover, Title, Author
return [...acc, {singleBookCover, singleBookTitle, singleBookAuthor}]
},
[]
).forEach( item => {
// For each item on our array, we creating h1
let title = document.createElement('h1');
title.textContent = `${item.singleBookTitle} by ${item.singleBookAuthor}`;
// img
let img = document.createElement('img');
img.src = item.singleBookCover;
img.alt = `${item.singleBookTitle} by ${item.singleBookAuthor}`;
// and div wrapper
let container = document.createElement('div');
// adding our child elements to wrapper
container.appendChild(title).appendChild(img);
// adding our wrapper to body
document.body.appendChild(container);
})
return book
}
Hope my answer will help you)
function handleResponse(obj) {
const container = document.getElementById("container")
obj.items.forEach((rec, index) => {
let singleBookCover =
rec.volumeInfo.imageLinks && rec.volumeInfo.imageLinks.smallThumbnail;
let singleBookTitle = rec.volumeInfo.title;
let singleBookAuthor = rec.volumeInfo.authors[0];
let book = document.createElement("div");
book.className = "book"
book.innerHTML = `
<div><h1>${singleBookTitle}<h1>
<p>${singleBookAuthor}</p>
<img src="${singleBookCover}"></img>
</div>
`
content.appendChild(book)
});
}
<div id="content" class="books">
</div>
<script src="https://www.googleapis.com/books/v1/volumes?q=clean+code&callback=handleResponse"></script>
I cannot get my images to change when I click each button name. Anyone know what the issue is with my code?
It's not letting me put my code in the description.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hmwk02</title>
</head>
<body>
<h1>Octocats</h1>
<img id="octocats" src= "https://octodex.github.com/images/original.png" alt="octocat" width="150"/>
<div id="buttons"></div>
<script>
let names= ["Castello", "Grinchtocat", "Mummytocat", "Adventure-Cat"];
let urls= ["https://octodex.github.com/images/catstello.png",
"https://octodex.github.com/images/grinchtocat.gif",
"https://octodex.github.com/images/mummytocat.gif",
"https://octodex.github.com/images/adventure-cat.png"];
let lines = "";
for(let i = 0; i< names.length; i++){
lines += '<button onlick="showPicture(' + i +')">' + names[i] + '</button><br/>'
}
document.getElementById("buttons").innerHTML = lines;
console.log(lines);
</script>
<script src="octocats.js"></script>
</body>
function showPicture(i) {
document.getElementById("octocat").src = urls[i];
console.log(i);
}
Your code is fine other than syntax errors, you misspelled onclick in your button tag and you misspelled the ID for the picture--it should be document.getElementById("octocats") not document.getElementById("octocat")
corrected code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hmwk02</title>
</head>
<body>
<h1>Octocats</h1>
<img id="octocats" src= "https://octodex.github.com/images/original.png" alt="octocat" width="150"/>
<div id="buttons"></div>
<script>
let names= ["Castello", "Grinchtocat", "Mummytocat", "Adventure-Cat"];
let urls= ["https://octodex.github.com/images/catstello.png",
"https://octodex.github.com/images/grinchtocat.gif",
"https://octodex.github.com/images/mummytocat.gif",
"https://octodex.github.com/images/adventure-cat.png"];
let lines = "";
for(let i = 0; i< names.length; i++){
lines += '<button onclick="showPicture(' + i +')">' + names[i] + '</button><br/>'
}
document.getElementById("buttons").innerHTML = lines;
console.log(lines);
</script>
<script>
function showPicture(i) {
document.getElementById("octocats").src = urls[i];
console.log(i);
}</script>
</body>
working codepen: https://codepen.io/anon/pen/YBYxgr
An alternative to using the for loop would be to map() the names array and simply use createElement() method to create a new <button> element with a click listener for each item in your names array (you should avoid using inline on* handlers (onclick, oninput, etc) and use IDs and event listeners instead).
Check and run the following Code Snippet for a practical example of what I have described above:
let names= ["Castello", "Grinchtocat", "Mummytocat", "Adventure-Cat"];
let urls= ["https://octodex.github.com/images/catstello.png", "https://octodex.github.com/images/grinchtocat.gif", "https://octodex.github.com/images/mummytocat.gif", "https://octodex.github.com/images/adventure-cat.png"];
names.map((e, i) => { // add function to each element in "names" array
let name = document.createElement("button"); // create <button> element for each item in "names" array
name.id = i; // assign respective index as id of each element
name.textContent = e; // assign item string as button text content
name.addEventListener("click", () => document.getElementById("octocats").src = urls[i]); // add click listener to each <button> that changes image src on click
document.getElementById("buttons").appendChild(name); // append the <button> elements to your `#buttons` div.
});
<h1>Octocats</h1>
<img id="octocats" src= "https://octodex.github.com/images/original.png" alt="octocat" width="150"/>
<div id="buttons"></div>
I want to loop though the array (array) and display the elements one by one only after clicking the button (bt). When i run this code it shows only the last element of the array (i.e honda). Please help me out
var hints = document.querySelector(".hint");
var array = ["Car", "bmw", "mercy", "porsche", "hyundai", "jeep", "honda"];
var bt = document.querySelector("button");
for (var i = 1; i < 6; i++){
bt.addEventListener("click", function(){
hints.textContent = array[i];
});
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Password</title>
<link rel="stylesheet" href="password.css" type="text/css">
</head>
<body>
<h1 class="hint"></h1>
<button type="button" name="button">Cick me</button>
<script src="password.js" charset="utf-8" type="text/javascript"></script>
</body>
</html>
Everytime, it's showing honda when you click on the button because at the time the click event is triggered the value of i is 6.
So,always when you click, it will always show array[6] value, which is 'honda'.
Anyways, please try the below, it should work:
let hints = document.querySelector(".hint");
let array = ["Car", "bmw", "mercy", "porsche", "hyundai", "jeep",
"honda"];
let bt = document.querySelector("button");
let count = 0;
bt.addEventListener('click', () => {
hints.textContent = array[count];
console.log('clicked!!');
count++;
if (count > array.length) {
console.log('no more values in the array!!');
return false;
}
})
I have also create a codepen for it. You can also have a look:
https://codepen.io/vishalkaului/pen/EbyjML
There is no for loop need. Keep a track of your count, and display the next one on click. See the edited code below:
var hints = document.querySelector(".hint");
var array = ["Car", "bmw", "mercy", "porsche", "hyundai", "jeep", "honda"];
var bt = document.querySelector("button");
var count = 0;
bt.addEventListener("click", function(){
if (count < array.length) {
hints.textContent = array[count];
count++;
}
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Password</title>
<link rel="stylesheet" href="password.css" type="text/css">
</head>
<body>
<h1 class="hint"></h1>
<button type="button" name="button">Cick me</button>
<script src="password.js" charset="utf-8" type="text/javascript"></script>
</body>
</html>
I want to change the word in the span tag every 1.5 seconds but so far it is just displaying the last word in the array 'list'.
Here is my javascript
var list = [
"websites",
"user interfaces"
];
setInterval(function() {
for(var count = 0; count < list.length; count++) {
document.getElementById("word").innerHTML = list[count];
}}, 1500);
And here is the html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<span id="word"></span>
</body>
</html>
You don't need a for loop, just use that setInterval, your counter or even simpler using Array manipulation:
var list = [
"websites",
"user interfaces",
"cool neh?"
];
var count = 0; // Separate your count
function changeWord() { // Separate your concerns
document.getElementById("word").innerHTML = list[count];
count = ++count % list.length; // Increment and loop counter
}
changeWord(); // First run,
setInterval(changeWord, 1500); // Subsequent loops
<span id="word"></span>
If you want to not use a counter but do it using array manipulation:
var list = [
"websites",
"user interfaces",
"cool neh?"
];
var ELWord = document.getElementById("word"); // Cache elements you use often
function changeWord() {
ELWord.innerHTML = list[0]; // Use always the first key.
list.push(list.shift()); // Push the first key to the end of list.
}
changeWord();
setInterval(changeWord, 1500);
<span id="word"></span>
P.S: The inverse would be using list.unshift(list.pop()) as you can see here.
Performance-wise the solution using counter should be faster but you have a small Array so the difference should not raise any concerns.
You may wanna try this. Not looping, just calling a changeWord function every 1.5 sec.
var list = [
"websites",
"user interfaces"
];
var count = 0;
function changeWord() {
document.getElementById("word").innerHTML = list[count];
count = count < list.length-1 ? count+1 : 0;
}
setInterval(function() { changeWord(); }, 1500);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<span id="word"></span>
</body>
</html>
I would do this job by setTimeout() as follows,
function loopTextContent(a, el, dur = 1500){
var i = -1,
len = a.length,
STID = 0,
looper = _ => (el.textContent = a[i = ++i%len], STID = setTimeout(looper,dur));
looper();
return _ => STID;
}
var list = ["websites", "user interfaces", "user experience", "whatever"],
getSTID = loopTextContent(list, document.getElementById("word"));
setTimeout(_ => clearTimeout(getSTID()),10000);
<span id="word"></span>
Better use setTimeout. Every iteration should have its own timeout. See also
(() => {
const words = document.querySelector('#words');
typeWords([
"web sites",
"user interfaces",
"rare items",
"other stuff",
"lizard sites",
"ftp sites",
"makebelief sites",
"fake news sites",
"et cetera"
]);
function typeWords(list) {
list.push(list.shift()) && (words.innerHTML = list[list.length-1]);
setTimeout(() => typeWords(list), 1500);
}
})();
<div id="words"></div>
The problem with your code is whenever your interval function is called,loop get executed and prints the element because you are replacing the whole innerHtml on each iteration.
You can try the following code if u want to print whole list element again and again after interval.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<span id="word"></span>
</body>
The javascript code :
var list = [
"websites",
"user interfaces"
];
var count=0;
function print()
{
document.getElementById("word").innerHTML = list[count];
count += 1;
count%=list.length;
}
setInterval( print(), 1000);