Javascript Stop Propagation - javascript

I have been trying to figure out how to get an index of a dynamically created element so that I can write a function to delete it (splice).
I have figured out how to get the index really manually, but the problem is that I am getting Propagation from my event delegation and I am not sure how to stop it.
I have tried putting stopPropagation(), preventDefault(), stopImmediatePropagation() at various points within the function and have spent the last hour reading around online trying to figure out how to stop it. I even tried setting the e.bubble to false with no avail.
Could someone point me in the right direction here? Im sure its my inexperience but I am just out of ideas as of now.
// Title of Question Set
const title = document.querySelector(".input_title-input");
// Array of Questions
const questions = [];
let chosen = [];
// Selected Question
let qChosen = [];
// Toggles if a new question is selected
let toggle = 0;
// Selecting Inputs and Button
let question = document.querySelector(".input_question-input");
let answer = document.querySelector(".input_answer-input");
let submit = document.querySelector(".input_submit-button");
let display = document.querySelector(".input_display");
let card = document.querySelector(".card_container");
let start = document.querySelector(".input_start-btn");
let guessInput = document.querySelector(".guess_input");
let submitGuess = document.querySelector(".submitGuess");
let nextQuestion = document.querySelector(".nextQuestion");
// Select all display items
let displayItems = document.getElementsByClassName("input_display-item");
// Select P quiz card values
let cardQuestion = document.querySelector(".quiz_question");
let cardAnswer = document.querySelector(".quiz_answer");
// Event Listener on Submit Button for Display Items Idividually
submit.addEventListener("click", function() {
if (question.value === "") {
question.classList.toggle("error");
answer.classList.toggle("error");
} else {
createObj();
let trashCan = createDisplayItem();
trashCan.addEventListener("click", function(e) {
console.log(this.parentNode);
console.log(questions);
console.log(e);
this.parentNode.remove();
});
inputReset();
toggle = questions.length;
start.removeAttribute("disabled");
}
});
start.addEventListener("click", function() {
console.log("clicked");
generateCard();
});
// Event Listener to test if guess is correct
submitGuess.addEventListener("click", function() {
if (guessInput.value.toLowerCase() === qChosen.answer.toLowerCase()) {
card.classList.toggle("flip");
submitGuess.disabled = true;
} else {
console.log("wrong or not working");
}
});
nextQuestion.addEventListener("click", function() {
card.classList.toggle("flip");
submitGuess.disabled = false;
setTimeout(generateCard, 1000);
});
// Create The object for inclusion to array
function createObj() {
let obj = {};
obj.question = question.value;
obj.answer = answer.value;
questions.push(obj);
}
// Resets inputs to blank after submit
function inputReset() {
question.value = "";
answer.value = "";
if (question.classList.contains("error")) {
question.classList.toggle("error");
answer.classList.toggle("error");
}
}
// Creates Each Display Item
function createDisplayItem() {
// Create new Div
let newUl = document.createElement("ul");
// Create Li and Image Elements
let liQuestion = document.createElement("li");
let liAnswer = document.createElement("li");
let trashCan = document.createElement("img");
// Set img src
trashCan.src = "../assets/trash.svg";
// Set classes
newUl.className = "input_display-item";
liQuestion.className = "input_display-question";
liAnswer.className = "input_display-answer";
trashCan.className = "input_display-delete";
// Set LI textContent
liQuestion.textContent = question.value;
liAnswer.textContent = answer.value;
// Append Children
display.appendChild(newUl);
newUl.appendChild(liQuestion);
newUl.appendChild(liAnswer);
return newUl.appendChild(trashCan);
}
//Generating Card Information per question
function generateCard() {
random();
if (toggle < 0) {
cardQuestion.textContent = "There are no more questions left";
cardAnswer.textContent = "There are no more questions left";
} else {
cardQuestion.textContent = qChosen.question;
cardAnswer.textContent = qChosen.answer;
}
}
// Choses a random value for the selection set
function random() {
if (questions.length === 0) {
toggle = -1;
} else {
let num = Math.floor(Math.random() * questions.length);
chosen = questions.splice(num, 1).concat(chosen);
qChosen = chosen[0];
}
}
// Notes
// I need to create a function that upon submit of a guess, checks its value against the answer textContent.
// I will likely need to make the text lowercase for the check to just make sure that they match exactly and that a capital letter wont create a false when its true.
/** Variables
---------------------------------------------------------*/
/** Reset
---------------------------------------------------------*/
* {
margin: 0;
padding: 0; }
*,
*::before,
*::after {
box-sizing: inherit; }
html {
box-sizing: border-box;
font-size: 62.5%; }
body {
font-weight: 400;
line-height: 1.5;
font-size: 2rem;
background-color: #bdbdc7; }
/** Primary Container
---------------------------------------------------------*/
.container {
max-width: 180rem;
display: flex; }
.flex {
display: flex;
justify-content: center;
align-items: center; }
.visible {
visibility: hidden; }
/** Input Section
---------------------------------------------------------*/
input[type="text"] {
padding: 0.5rem;
width: auto;
min-width: 100%;
line-height: 2rem; }
.input {
width: 40rem;
height: 100%;
padding: 1rem;
background-color: #ccc;
display: flex;
align-items: flex-start;
flex-direction: column; }
.input_title {
width: 100%;
display: flex;
flex-direction: column; }
.input_title-label {
display: flex;
justify-content: center; }
.input_title-input {
padding: 0.5rem; }
.input_question {
width: 100%;
display: flex;
flex-direction: column; }
.input_question-label {
display: flex;
justify-content: center; }
.input_question-input {
padding: 0.5rem; }
.input_answer {
width: 100%;
display: flex;
flex-direction: column; }
.input_answer-label {
display: flex;
justify-content: center; }
.input_answer-input {
padding: 0.5rem; }
.input_question-input.error, .input_answer-input.error {
border: 2px red solid; }
.input_submit {
width: 100%; }
.input_submit-button {
margin-top: 1rem;
padding: 0 1.5rem; }
.input_start {
width: 100%; }
.input_display {
width: 100%;
font-size: 1.5rem;
padding: 2rem 0 1rem 0; }
.input_display-item {
margin-bottom: 1rem;
padding: .2rem 2rem;
text-transform: capitalize;
background-color: #fff;
border-radius: 1rem;
list-style: none;
display: flex;
justify-content: space-between;
align-items: center; }
.input_display-item:nth-child(odd) {
background-color: #aaa;
border-radius: 1rem; }
.input_display-delete {
height: 1.8rem;
width: 1.8rem; }
.input :not(.input_display) div {
padding-bottom: 2rem; }
/** Quiz Card
---------------------------------------------------------*/
.card {
display: flex;
justify-content: center;
align-items: center;
width: 100%; }
.card_container {
transform-style: preserve-3d;
perspective: 1000px;
width: 60rem;
margin: 1rem;
cursor: pointer; }
.card_container .front {
transform: rotateY(0deg);
transform-style: preserve-3d; }
.card_container .front:after {
position: absolute;
top: 0;
left: 0;
z-index: 1;
width: 100%;
height: 100%;
content: "";
display: block;
opacity: 0.6;
background-color: #000;
backface-visibility: hidden;
border-radius: 10px; }
.card_container .back {
position: absolute;
top: 0;
left: 0;
width: 100%;
background-color: #cedce7;
background: linear-gradient(45deg, #dedce7 0%, #596a72 100%);
transform: rotateY(180deg);
transform-style: preserve-3d; }
.card_container .front,
.card_container .back {
background-color: red;
background-size: cover;
background-position: center;
transition: transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1);
transition: transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1);
backface-visibility: hidden;
text-align: center;
min-height: 500px;
height: auto;
border-radius: 10px;
color: #fff;
font-size: 1.5rem; }
.flip {
transition: transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1);
transition: transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1); }
.flip .back {
transform: rotateY(0deg);
transform-style: preserve-3d; }
.flip .front {
transform: rotateY(-180deg);
transform-style: preserve-3d; }
.inner {
transform: translateY(-50%) translateZ(60px) scale(0.94);
top: 50%;
position: absolute;
left: 0;
width: 100%;
padding: 2rem;
box-sizing: border-box;
outline: 1px solid transparent;
perspective: inherit;
z-index: 2; }
.front .inner p {
font-size: 2rem;
margin-bottom: 2rem;
position: relative; }
.card_container-guess {
padding-top: 2rem; }
.card_container-guess .guess_input {
width: 2rem;
margin: 1rem auto;
padding: 1rem;
border-radius: 1rem;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.55), 0px 1px 1px rgba(255, 255, 255, 0.5);
border: 1px solid #666;
opacity: 0.6; }
.card_container-guess .guess_input:hover, .card_container-guess .guess_input:focus {
opacity: .8;
color: #08c;
box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25), inset 0px 3px 6px rgba(0, 0, 0, 0.25); }
.btnNew {
height: 5rem;
width: 12rem;
margin: 1.5rem 3rem 1rem 0;
font-weight: 700;
color: #333;
background-image: linear-gradient(top, #f4f1ee, #fff);
box-shadow: 0px 8px 30px 1px rgba(0, 0, 0, 0.3), inset 0px 4px 1px 1px white, inset 0px -3px 1px 1px rgba(204, 198, 197, 0.5);
border-radius: 5%;
position: relative;
transition: all .1s linear;
outline: none; }
.btnNew:after {
color: #e9e6e4;
content: "";
display: block;
font-size: 30px;
height: 3rem;
text-decoration: none;
text-shadow: 0px -1px 1px #bdb5b4, 1px 1px 1px white;
position: absolute;
width: 3rem; }
.btnNew:hover {
background-image: linear-gradient(top, #fff, #f4f1ee);
color: #0088cc; }
.btnNew:active {
background-image: linear-gradient(top, #efedec, #f7f4f4);
box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.4), inset opx -3px 1px 1px rgba(204, 198, 197, 0.5);
outline: none; }
.btnNew:active:after {
color: #dbd2d2;
text-shadow: 0px -1px 1px #bdb5b4, 0px 1px 1px white;
outline: none; }
<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">
<title>Flash</title>
<!-- Custom CSS -->
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<div class="container">
<section class="input">
<div class="input_title">
<label class="input_title-label" for="title">Enter a Title</label>
<input class="input_title-input" id="title" type="text" placeholder="List of Towels">
</div>
<div class="input_question">
<label class="input_question-label" for="question">Enter a Question</label>
<input class="input_question-input" id="question" type="text" placeholder="What is 42?">
</div>
<div class="input_answer">
<label class="input_answer-label" for="answer">Enter an Answer</label>
<input class="input_answer-input" id="answer" type="text" placeholder="The Meaning Life, Universe, and Everything">
</div>
<div class="input_submit flex">
<button class="input_submit-button btnNew">Submit</button>
</div>
<div class="input_display"></div>
<div class="input_start flex">
<button type="button" class="input_start-btn btnNew" disabled>Start Quiz</button>
</div>
</section>
<section class="card">
<div class="card_container">
<div class="front">
<div class="inner">
<p class="quiz_question">Question</p>
</div>
</div>
<div class="back">
<div class="inner">
<p class="quiz_answer">Answer</p>
</div>
</div>
<div class="card_container-guess">
<input type="text" class="guess_input">
<button class="submitGuess btnNew">Submit Guess</button>
<button class="nextQuestion btnNew">Next Question</button>
</div>
</div>
</section>
</div>
<!-- Custom JS -->
<script src="js/scripts.js"></script>
</body>
</html>

I am wanting to figure out how to delete an item from the list
How about we change the last line of the function createDisplayItem to ..
function createDisplayItem(){
...
return newUl.appendChild(trashCan) // Added return
}
Now, you have an instance of the newly created trash can element being returned to the calling code, so now all we have to do is add a click event to this specific trash can element and let it delete its parent ul ..
submit.addEventListener("click", function() {
...
let trashCan = createDisplayItem();
trashCan.addEventListener('click', function(){
confirm('Are you sure you want to delete this?')
&& this.parentNode.remove()
})
...
});
So, since now in this code, each trash can takes care of its own parent element, you do not have to worry about finding the index from the parent display element anymore.

Related

How can I prevent the app from adding the same text each time add favourite icon is clicked?

// GET
const getAdviceNumber = document.querySelector('#adviceNumber');
const adviceResultsDiv = document.querySelector('#adviceResults');
const diceBtn = document.querySelector('#spinDice');
const staticText = document.querySelector('#static');
const favouriteSection = document.querySelector('.favouriteSection')
diceBtn.addEventListener('click', () => {
const getAPI = async () => {
// Call API
/* eslint-disable */
const res = await axios.get('https://api.adviceslip.com/advice');
// remove static text
staticText.remove();
// Generate spin on btn
const element = document.querySelector('#spinDice');
element.classList.add('rotateMe');
setTimeout(() => element.classList.remove('rotateMe'), 800);
// generate unique id number
const header = document.createElement('h1');
header.className = 'title';
header.append(` ADVICE # ${res.data.slip.id}`);
while (getAdviceNumber.childElementCount > 0) {
getAdviceNumber.firstChild.remove();
}
getAdviceNumber.append(header);
// generate unique advice
const para = document.createElement('p');
para.className = 'para';
para.append(`"${res.data.slip.advice}"`);
while (adviceResultsDiv.childElementCount > 0) {
adviceResultsDiv.firstChild.remove();
}
adviceResultsDiv.append(para);
//generate add to favourites button
const addFavourite = document.createElement('p');
addFavourite.className = 'fav';
addFavourite.innerHTML = `<p>Add to Favourites<i class="fa-solid fa-folder-plus"></i></p>`;
while (favouriteSection.childElementCount > 0) {
favouriteSection.firstChild.remove();
}
favouriteSection.append(addFavourite)
};
getAPI();
favouriteSection.addEventListener('click', () => {
const favouriteItem = document.createElement('p');
favouriteItem.innerHTML = `<p class="icons"><i class="fa-solid fa-magnifying-glass"></i> <i class="fa-solid fa-trash-can"></i></p>`
favouriteItem.className = 'favouriteItemBorder';
favouriteSection.append(favouriteItem)
favouriteItem.append(`${getAdviceNumber.textContent}: ${ adviceResultsDiv.textContent}`)
})
});
body {
background-color: hsl(218, 23%, 16%);
font-family: Arial, Helvetica, sans-serif;
}
#advice-container {
background-color: hsl(217, 19%, 38%);
border-radius: 20px;
position: absolute;
-ms-transform: translateY(-50%);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
padding-bottom: 40px;
}
h2 {
color: hsl(193, 38%, 86%);
text-align: center;
}
.title {
color: hsl(150, 100%, 66%);
font-size: 15px;
text-align: center;
margin-top: 20px;
}
.para {
color: hsl(193, 38%, 86%);
font-size: 28px;
font-weight: 500;
text-align: center;
margin: 20px 20px 0 20px;
}
.btn {
margin-top: 40px;
margin-bottom: -75px;
}
.dice-container {
background-color: hsl(150, 100%, 66%);
border: solid 2px hsl(193, 38%, 86%);
border-radius: 33px;
margin: 20px 110px 0 110px;
}
.dice-container:hover {
box-shadow: 0 0 30px -2px #52ffa8;
}
.fa-dice-five {
font-size: 50px;
width: 100%;
text-align: center;
padding-top: 10px;
padding-bottom: 10px;
padding-right: 10px;
/* transform: rotate(90deg); */
}
.rotate {
transition: all 0s ease;
transform: rotate(0deg);
}
.rotateMe {
transition: all 0.3s ease;
transform: rotate(90deg);
}
#icons {
color: hsl(193, 38%, 86%);
}
.icon-container {
padding: 20px 120px 0 120px;
width: 100%;
}
.fa-grip-lines-vertical {
margin: 0 10px 0 10px;
}
.line {
width: 100%;
}
.favouriteSection {
position: absolute;
top: 70%;
}
.fav {
color: #52ffa8;
font-size: 32px;
margin: 20px;
}
.fa-folder-plus {
margin-left: 10px;
}
.favouriteItemBorder {
border: 2px solid white;
width: 300px;
height: 60px;
margin: 20px;
padding: 10px;
text-align: center;
}
.icons {
position:absolute;
bottom:10px;
left: 40%;
font-size: 20px;
}
/* desktop ..................................................................................... */
#media screen and (min-width: 720px) {
#advice-container {
display: flex;
width: 900px;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- displays site properly based on user's device -->
<title>Oshane| Advice generator app</title>
<link rel="stylesheet" href="style.css">
<script src="https://kit.fontawesome.com/030a66e167.js" crossorigin="anonymous"></script>
</head>
<body>
<section id="advice-container">
<div id="static">
<h2>Click the Dice Button <br><br> below <br><br> to get advice</h2>
</div>
<div id="adviceNumber"> </div>
<div id="adviceResults"></div>
<div class="btn" id="getDataBtn">
<button id="spinDice" class="dice-container rotate" type="submit"><i class="fa-solid fa-dice-five"></i></button>
</div>
</section>
<section class="favouriteSection">
</section>
<!-- <script src="./node_modules/axios/dist/axios.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="app.js"></script>
</body>
</html>
]2]2how can I prevent this from adding the same text each time the add favourite icon is clicked? It should just add it once and if the add favourite btn is selected again and the quote already exists it should not repeat adding the same ones. I tried a few stuff but as I am a beginner those did not work.
Please anyone can assist?
You can check for something before adding/pushing into favorites array.
Check if something like id(best) or string exists in the arrray and if so - return, else push
Step by step, this is what you are missing:
Create an empty object.
Each time the user clicks the "Add to Favourites" button, you should check if it's already in that object.
If it is, you are done handling that click event.
If it is not, you should add it to the object and then proceed with the logic you currently have to update the UI.
Simplified example:
const rollButton = document.getElementById('roll');
const numberElement = document.getElementById('number');
const addToFavouritesButton = document.getElementById('addToFavourites');
const favouritesElement = document.getElementById('favourites');
let number = null;
rollButton.addEventListener('click', () => {
numberElement.textContent = number = Math.floor(Math.random() * 10);
addToFavouritesButton.removeAttribute('disabled');
});
const favourites = {};
addToFavouritesButton.addEventListener('click', () => {
if (favourites[number]) return;
favourites[number] = true;
favouritesElement.textContent = Object.keys(favourites).sort((a, b) => a - b).join(', ');
if (Object.keys(favourites).length === 10) {
numberElement.textContent = '🎉';
rollButton.setAttribute('disabled', true);
addToFavouritesButton.setAttribute('disabled', true);
}
});
body,
button {
font-family: monospace;
}
p {
text-align: center;
}
button {
border: 3px solid black;
border-radius: 4px;
background: transparent;
padding: 8px 16px;
}
button:hover {
background: yellow;
}
button:disabled {
border-color: #CCC;
color: #CCC;
background: transparent;
}
#number {
border: 3px solid black;
width: 48px;
height: 48px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 4px;
}
#favourites {
display: inline-flex;
align-items: center;
justify-content: center;
border: 3px solid black;
border-radius: 4px;
background: transparent;
padding: 8px 16px;
}
<p>
<button id="roll">🎲 Roll Dice</button>
<button id="addToFavourites" disabled>⭐ Add to Favourites</button>
</p>
<p>
<span id="number">?</span>
</p>
<p>
<span id="favourites"> </span>
</p>

Local storage data not saving on page refresh

I am creating a settings portion on a website. I want the features chosen to be "saved" and kept when the page refreshes. I attempted this but it seems to just reset the form when I refresh the page. Another issue is when I click on the cancel button, the toggle buttons reset but the dropdown comes back blank instead of going back to the placeholder "select timezone". The issue most likely lies in my javascript code below. It's also throwing an error in stack overflow but works properly on my website (minus the issues described above). Any suggestions would be much appreciated!
// ---------- TOGGLE BTN ----------
const toggle = document.getElementsByClassName("toggle");
const labels = document.getElementsByClassName("labels");
for(let i=0; i < 2; i++) {
labels[i].innerHTML = "OFF";
toggle[i].addEventListener( "click", () => {
if(labels[i].innerHTML == "OFF") {
// console.log("button toggled");
labels[i].classList.add("on");
labels[i].innerHTML= "ON";
} else {
labels[i].classList.remove("on");
labels[i].innerHTML = "OFF";
}
});
}
// ---------- LOCAL STORAGE DATA ----------
const save = document.getElementById("save");
const cancel = document.getElementById("cancel");
const emailBtn = document.getElementById("togBtn");
const publicBtn = document.getElementById("togBtn2");
const zone = document.getElementById("timezone");
// emailBtn.value = data;
// publicBtn.value = data;
// zone.value = data;
const data = {
email: emailBtn.value,
privacy: publicBtn.value,
timezone: zone.value
}
var emailVal = localStorage.getItem("email");
var privacyVal = localStorage.getItem("privacy");
var zoneVal = localStorage.getItem("timezone");
save.addEventListener('click', () => {
localStorage.setItem("email", emailBtn.value);
localStorage.setItem("privacy", publicBtn.value);
localStorage.setItem("timezone", zone.value);
});
cancel.addEventListener('click', () => {
localStorage.clear();
for(let i=0; i < 2; i++) {
labels[i].innerHTML = "OFF";
labels[i].classList.remove("on");
}
emailBtn.checked = false;
publicBtn.checked =false;
zone.value = 'Select Timezone';
});
.settings {
padding-left: 15px;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.settings h3 {
flex-basis: 100%;
}
.button1,
.button2 {
flex-basis: 100%;
display: flex;
align-items:center;
}
label {
flex-basis: 90%;
}
input {
flex-basis: 10%;
}
.form-field {
flex-basis: 100%;
background-color: rgb(241, 240, 240);
border: 1px solid lightgrey;
color: grey;
border-radius: 5px;
padding: 10px;
margin: 0 15px 10px 0;
}
.settings-button {
display: flex;
justify-content: center;
}
button {
margin: 10px 15px 10px 0;
padding: 10px;
border: 1px solid lightgrey;
border-radius: 5px;
}
#save,
#cancel {
flex-basis: 50%;
}
#save {
background-color: #7477BF;
color: white;
}
#cancel {
background-color: darkgray;
color: white;
}
#timezone {
margin-top:25px;
}
/* toggle button */
.toggle {
-webkit-appearance: none;
-webkit-tap-highlight-color: transparent;
position: relative;
outline: 0;
cursor: pointer;
margin: 10px 15px;
}
.toggle:after {
content: '';
width: 80px;
height: 28px;
display: inline-block;
background: rgba(196, 195, 195, 0.55);
border: 2px solid rgba(196, 195, 195, 0.55);
border-radius: 18px;
clear: both;
}
.toggle:before {
content: '';
width: 20px;
height: 20px;
display: block;
position: absolute;
top: 3px;
/* left: 0;
top: -3px; */
border: 2px solid rgba(196, 195, 195, 0.55);
border-radius: 50%;
background: rgb(255, 255, 255);
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.6);
}
.toggle:checked:before {
left: 54px;
box-shadow: -1px 1px 3px rgba(0, 0, 0, 0.6);
}
.toggle:checked:after {
background: #7477BF;
}
.toggle,
.toggle:before,
.toggle:after,
.toggle:checked:before,
.toggle:checked:after {
transition: ease .4s;
-webkit-transition: ease .4s;
-moz-transition: ease .4s;
-o-transition: ease .4s;
}
.labels {
color: gray;
position: relative;
font-size: 15px;
transform: translate(-48px, -3px);
}
.on {
color: white;
transform: translate(-90px, -3px);
}
<section class="settings" id="settings">
<h3>Settings</h3>
<!-- custom CSS toggle code-->
<div class="button1">
<label for="togBtn">Send Email Notfications </label>
<input type="checkbox" class="toggle" id="togBtn">
<span class="labels"></span>
</div>
<div class="button2">
<label for="togBtn2">Set Profile to Public </label>
<input type="checkbox" class="toggle" id="togBtn2">
<span class="labels"></span>
</div>
<select class="form-field" id="timezone">
<option disabled selected>Select a Timezone</option>
<option>Eastern</option>
<option>Western</option>
<!-- more options -->
</select>
<div class="settings-button" >
<button class="button-primary" id="save">Save</button>
<button class="button-disabled" id="cancel">Cancel</button>
</div>
</section>
here a working example.
The problems with your code were that you were using emailBtn.value and publicBtn.value instead of emailBtn.checked and publicBtn.checked (they are checkbox so in order to get the correct value you have to read che checked property) and you were not loading the saved values on document load (the function inside window.addEventListener("load", ...) in my example.
Hope this helps you.

Accordion Javascript plus sign doesn't work

I am doing an accordion in JavaScipt, in my HTML I have two separate divs for questions title and separate div for "+" sign. My goal is when I click on div with class accordionTitle I want "+" sign change to "-" and at the same time show the answer. I am pretty new to development, what the best approach here? Can you help me?
HTML:
<section class="qnaSection">
<h1 class="qnaTitle">FAQ</h1>
<div id="qnaContainer" class="qnaContainer"></div>
</section>
CSS:
.qnaSection {
background-color: rgb(35, 57, 94);
color: var(--brown);
}
.qnaTitle {
text-align: center;
margin: 10px 0;
font-size: 28px;
}
.qnaContainer {
width: 90%;
max-width: 1000px;
margin: 20px auto;
}
.accordionItem {
background-color: rgb(222, 222, 222);
color: black;
margin: 10px 0;
border-radius: 10px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.25);
}
.accordionItemTitle {
padding: 1rem;
min-height: 3.5rem;
width: 100%;
line-height: 1.25rem;
font-weight: bold;
display: flex;
justify-content: space-between;
position: relative;
cursor: pointer;
box-sizing: border-box;
}
.accordionItemPush {
/* content: '\002B'; */
font-size: 2rem;
/* position: absolute;
right: 1rem; */
transition: transform 0.2s ease-in-out;
min-width: 70px;
display: flex;
justify-content: space-around;
align-items: center;
}
.accordionItemPush.active::after {
/* content: '\2212'; */
transform: rotate(45deg);
}
.accordionContent {
max-height: 0;
overflow: hidden;
}
.accordionParagraph {
padding: 1rem;
line-height: 1.5rem;
border-top: 1px solid;
border-image: linear-gradient(to right, transparent, rgb(101, 101, 136), transparent) 1 ;
transition: max-heigth 0.2s ease-out;
}
.accordionItem.active + .accordionContent {
max-height: auto;
display: block;
}
JS:
const questions = [] // array with questions
const qnaContainer = document.getElementById("qnaContainer")
const generateTitleHtml = title => {
return `
<h3>${title}</h3>
`
}
const generateQuestionHtml = item => {
return `
<div class="accordionItem">
<div class="accordionItemTitle">
<p>${item.question}</p>
<div class="accordionItemPush">
+
</div>
</div>
<div class="accordionContent">
<p class="accordionParagraph">${item.answer}</p>
</div>
</div>
`
}
const listQ = questions => {
qnaContainer.insertAdjacentHTML('beforeend', generateTitleHtml(questions.title))
questions.items.forEach( question => {
qnaContainer.insertAdjacentHTML('beforeend', generateQuestionHtml(question))
})
}
listQ(questions.regularQuestions)
listQ(questions.membershipBilling)
const accordionItemHeaders = document.querySelectorAll(".accordionItemTitle");
const toggleBar = () => {
accordionItemHeaders.forEach(item => {
item.addEventListener("click", () => {
checkCurrentlyActiveItem(item)
toggleActive(item)
})
});
}
const checkCurrentlyActiveItem = (accordionItemHeader) => {
const currentlyActiveItem = document.querySelector(".accordionItemTitle.active");
if(currentlyActiveItem && currentlyActiveItem!==accordionItemHeader) {
currentlyActiveItem.classList.toggle("active");
currentlyActiveItem.nextElementSibling.style.maxHeight = 0;
}
}
const toggleActive = (accordionItemHeader, itemBtn) => {
accordionItemHeader.classList.toggle("active");
const accordionItemBody = accordionItemHeader.nextElementSibling;
if(accordionItemHeader.classList.contains("active")) {
accordionItemBody.style.maxHeight = accordionItemBody.scrollHeight + "px";
}
else {
accordionItemBody.style.maxHeight = 0;
}
}
toggleBar()
What you could do is: instead of putting the HTML code in the javascript, create elements with document.createElement("elementName") and then set its class name or id. Then you can set an onclick-event on the element and change its innerText or innerHTML to a "-". I think this link can be useful. If you have any questions, ask them :)

How to Append a child to the outerHTML of the father element rather than inside?

Hello how to Append a child element using the outerHTML method on the father's element so the icons will go to the outer side of the targeted element rather than inside of it?
in the snippet you will se the icons inside the box I want them out side
in other worlds, I want the icons to be below the box rather than inside
I tried flex and other CSS stuff no luck.
//on select
const deleteExisting = document.querySelectorAll('.solidOnClickDelete');
// Item Lists
const itemRows = document.querySelectorAll('.drag-item-list');
const mondayList = document.getElementById('mondaylist');
// Items
let updateOnLoad = false
// Initialize Arrays
let mondayListArray = [];
let listarrays = [];
// Drag Functionality
let dragged;
let updateRow = false;
let dragging = false;
let currentRow;
// Get Arrays from localStorage if available, set default values if not
function getSavedRows() {
mondayListArray = ['Work 7.00-15.00', 'Doctor visit'];
}
// Set localStorage Arrays
function updateSavedRows() {
listarrays = [mondayListArray];
const arrayNames = ['monday']
arrayNames.forEach((arrayName, index) => {
//localStorage.setItem(`${arrayName}Items`, JSON.stringify(listarrays[index]))
});
}
//Filter to remove null from deleted items //
function filterArray(array) {
const filteredArray = array.filter(item => item !== null);
return filteredArray;
}
// Create DOM Elements for each list item
function createItemEl(rowEl, row, item, index) {
// List Item
const listEl = document.createElement('li')
listEl.classList.add('day-item');
listEl.textContent = item;
listEl.draggable = true;
listEl.setAttribute('ondragstart', 'drag(event)')
listEl.contentEditable = true;
listEl.id = index;
const divOptions = document.createElement('span');
divOptions.classList.add('father', 'hidden');
divOptions.contentEditable = false;
listEl.onfocus = () => divOptions.classList.remove('hidden');
listEl.onblur = () => divOptions.classList.add('hidden');
const iconDelete = document.createElement('i');
const iconYes = document.createElement('i');
iconYes.classList.add('far', 'fa-check-circle', 'fa-2x');
iconDelete.classList.add('far', 'fa-times-circle', 'fa-2x');
iconYes.setAttribute('onclick', `updateItem(${index}, ${row})`);
iconDelete.setAttribute('onclick', `deleteItemOnClick(${index}, ${row})`);
//Append everything //
rowEl.appendChild(listEl);
listEl.appendChild(divOptions);
divOptions.appendChild(iconYes);
divOptions.appendChild(iconDelete);
};
// Update Columns in DOM - Reset HTML, Filter Array, Update localStorage
function updateDOM() {
// Check localStorage once
if (!updateOnLoad) {
getSavedRows();
}
mondayList.textContent = '';
mondayListArray.forEach((mondayitem, index) => {
createItemEl(mondayList, 0, mondayitem, index);
});
mondayListArray = filterArray(mondayListArray)
updateOnLoad = true;
updateSavedRows();
}
// Delete on click - //
function deleteItemOnClick(id, row) {
//let deleteItem = document.getElementsByClassName('solidOnClickDelete');
const selectedArray = listarrays[row];
delete selectedArray[id]
/*
deleteItem[0].onclick = function () { delete selectedArray[id] };
console.log(deleteItem[0]);
updateDOM();*/
updateDOM();
};
// add To Task Array
function addToRow(row) {
const itemText = addTask[row].textContent;
const selectedArray = listarrays[row];
selectedArray.push(itemText);
addTask[row].textContent = '';
updateDOM();
}
// reBuild Arrays
function rebulidArrays() {
mondayListArray = [];
for (i = 0; i < mondayList.children.length; i++) {
mondayListArray.push(mondayList.children[i].textContent);
}
updateDOM();
}
// On Load
updateDOM();
html {
box-sizing: border-box;
}
:root {
/* Light Theme Default */
/* Main Colors */
--primary-color: rgb(255, 255, 255);
--primary-variant: #b9b9b9;
--secondary-color: #5c5c5c;
/* Text on Main Colors */
--on-primary: rgb(54, 54, 54);
--on-background: rgb(78, 78, 78);
--on-background-alt: rgba(253, 253, 253, 0.952);
/* Background */
--background: rgb(255, 255, 255);
/* Box Shadow */
--box-shadow: 0 5px 20px 1px rgba(54, 54, 54, 0.5);
}
[data-theme="dark"] {
--primary-color: rgb(39, 39, 39);
--primary-variant: #777777;
--secondary-color: #e4e4e4;
--on-primary: rgb(173, 173, 173);
--on-background: rgba(255, 255, 255, 0.9);
--on-background-alt: rgba(0, 0, 0, 0.7);
--background: #202020;
}
body {
margin: 0;
color: var(--on-primary);
background-color:var(--primary-color);
font-family: 'Quicksand', sans-serif;
}
.slider.round::before {
border-radius: 50%;
}
.main-title {
font-size: 3rem;
color: var(--on-background);
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.main-container {
margin: 20px;
}
.days-list {
display: flex;
flex-direction:column;
}
/* rows / poulation */
.day-row,.populating-btns {
margin: 10px 10px;
background-color: rgba(95, 95, 95, 0.4);
border-radius: 3px;
display: flex;
overflow-x: hidden;
flex-wrap: wrap;
}
.dayFunction {
align-content: center;
justify-content: center;
margin-top: auto;
margin-bottom: auto;
}
.Flex-right {
display: flex;
float: right;
}
.Monday-row .header,
.Monday-row .over {
background-color: var( --on-primary);
}
.hidden {
display: none;
}
.day-item {
margin: 10px;
padding: 10px;
height: fit-content;
background-color:var(--secondary-color);
color: var(--primary-color);
border-radius: 3px;
line-height: 1.5rem;
letter-spacing: 1px;
cursor: pointer;
transition: 1s;
}
.day-item:focus {
outline: none;
background-color: white;
color: black;
}
/* Add Button Group */
.add-btns {
display: flex;
justify-content: space-between;
}
.add-btn {
margin: 10px;
padding: 5px 10px;
display: flex;
align-items: center;
cursor: pointer;
width: fit-content;
border-radius: 5px;
transition: all 0.3s ease-in;
user-select: none;
}
.add-task {
margin: 10px;
padding: 5px 10px;
display: flex;
align-items: center;
cursor: pointer;
width: fit-content;
border-radius: 5px;
transition: all 0.3s ease-in;
user-select: none;
background-color:var(--on-primary);
color:var(--on-background-alt);
}
.add-btn,.add-task:hover {
background-color: rgba(255, 255, 255, 0.9);
color: black;
}
.add-btn:active {
transform: scale(0.97);
}
.add-btn-extend {
margin: 10px;
padding: 10px 40px 10px 40px;
display: flex;
align-items: center;
cursor: pointer;
border-radius: 5px;
transition: all 0.5s ease-in;
user-select: none;
background-color: rgba(12, 178, 207, 0.603);
}
.add-btn-extend:hover {
background-color: rgba(255, 255, 255, 0.9);
color: black;
}
.solidOnClick , .solidOnClickDelete {
margin: 10px;
padding: 5px 10px;
align-items: center;
cursor: pointer;
width: fit-content;
border-radius: 5px;
transition: all 0.3s ease-in;
user-select: none;
background-color: var(--primary-variant);
}
.solidonclick:hover{
transition: all 0.5s ease-in;
filter: brightness(95%);
color: rgb(0, 0, 0);
background-color: rgba(228, 228, 228, 0.842);
}
.father {
display: flex;
justify-content: space-between;
}
.fa-check-circle {
color: green;
}
.fa-times-circle {
color: red;
}
.hidden {
display: none;
}
<!DOCTYPE html>
<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>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.1/css/all.css"
<link rel="stylesheet" href="style.css">
</head>
<body>
<li class="day-row Monday-row">
<div id="Mondaycontent">
<ul id="mondaylist" class="drag-item-list Flex-right" ondrop="drop(event)" ondragover="dropin(event)"
ondragenter="dragenter(0)">
</ul>
</div>
</div>
<!--Add Task To Li Later showInputBox()-->
<div class="add-container">
<div class="add-item" contenteditable="true"></div>
</div>
</li>
</body>
<script src="js.js"></script>
</html>
In terms of HTML semantics, a list item <li> tag should only be used inside of an unordered <ul> or ordered <ol> list. There is a list element acting as the parent container <li class="day-row Monday-row"> so that should probably be changed to a <div>.
The <script> tag for your external JavaScript file is also placed outside the <body> which is invalid. It needs to be placed before the body close </body> or within the <head> for the page to load the script.
To address moving the checkmark and red X icons outside of the list item content box after clicking the items, you can simply append those <span> tags into the outer container <div id="MondayContent">.
function createItemEl(rowEl, row, item, index) {
// parent container
const parentDiv = document.querySelector("#Mondaycontent");
...
// append icons to parent container
parentDiv.appendChild(divOptions);
}
Lastly, use CSS and some JavaScript to position the icons accordingly under each list item.
After the updateDOM() method, I positioned the second <span> tag underneath the "Doctor visit" list item. Instead of using JavaScript, you could also target that tag using a CSS selector such as .father:last-child.
// Position the icons for Doctor visit item
const icons = document.querySelectorAll(".father");
icons[1].style.left = "12.5rem";
/* Parent div container */
#Mondaycontent {
display: flex;
flex-direction: column;
}
#Mondaycontent .father {
position: relative;
left: 3rem;
width: 5rem;
margin-bottom: .5rem;
}
/* Use this if you don't want to style the second span tag with JS */
#Mondaycontent .father:last-child {
left: 12.5rem;
}
//on select
const deleteExisting = document.querySelectorAll('.solidOnClickDelete');
// Item Lists
const itemRows = document.querySelectorAll('.drag-item-list');
const mondayList = document.getElementById('mondaylist');
// Items
let updateOnLoad = false
// Initialize Arrays
let mondayListArray = [];
let listarrays = [];
// Drag Functionality
let dragged;
let updateRow = false;
let dragging = false;
let currentRow;
// Get Arrays from localStorage if available, set default values if not
function getSavedRows() {
mondayListArray = ['Work 7.00-15.00', 'Doctor visit'];
}
// Set localStorage Arrays
function updateSavedRows() {
listarrays = [mondayListArray];
const arrayNames = ['monday']
arrayNames.forEach((arrayName, index) => {
//localStorage.setItem(`${arrayName}Items`, JSON.stringify(listarrays[index]))
});
}
//Filter to remove null from deleted items //
function filterArray(array) {
const filteredArray = array.filter(item => item !== null);
return filteredArray;
}
// Create DOM Elements for each list item
function createItemEl(rowEl, row, item, index) {
// parent container
const parentDiv = document.querySelector("#Mondaycontent");
// List Item
const listEl = document.createElement('li')
listEl.classList.add('day-item');
listEl.textContent = item;
listEl.draggable = true;
listEl.setAttribute('ondragstart', 'drag(event)')
listEl.contentEditable = true;
listEl.id = index;
const divOptions = document.createElement('span');
divOptions.classList.add('father', 'hidden');
divOptions.contentEditable = false;
listEl.onfocus = () => divOptions.classList.remove('hidden');
listEl.onblur = () => divOptions.classList.add('hidden');
const iconDelete = document.createElement('i');
const iconYes = document.createElement('i');
iconYes.classList.add('far', 'fa-check-circle', 'fa-2x');
iconDelete.classList.add('far', 'fa-times-circle', 'fa-2x');
iconYes.setAttribute('onclick', `updateItem(${index}, ${row})`);
iconDelete.setAttribute('onclick', `deleteItemOnClick(${index}, ${row})`);
//Append everything //
rowEl.appendChild(listEl);
listEl.appendChild(divOptions);
parentDiv.appendChild(divOptions);
divOptions.appendChild(iconYes);
divOptions.appendChild(iconDelete);
};
// Update Columns in DOM - Reset HTML, Filter Array, Update localStorage
function updateDOM() {
// Check localStorage once
if (!updateOnLoad) {
getSavedRows();
}
mondayList.textContent = '';
mondayListArray.forEach((mondayitem, index) => {
createItemEl(mondayList, 0, mondayitem, index);
});
mondayListArray = filterArray(mondayListArray)
updateOnLoad = true;
updateSavedRows();
}
// Delete on click - //
function deleteItemOnClick(id, row) {
//let deleteItem = document.getElementsByClassName('solidOnClickDelete');
const selectedArray = listarrays[row];
delete selectedArray[id]
/*
deleteItem[0].onclick = function () { delete selectedArray[id] };
console.log(deleteItem[0]);
updateDOM();*/
updateDOM();
};
// add To Task Array
function addToRow(row) {
const itemText = addTask[row].textContent;
const selectedArray = listarrays[row];
selectedArray.push(itemText);
addTask[row].textContent = '';
updateDOM();
}
// reBuild Arrays
function rebulidArrays() {
mondayListArray = [];
for (i = 0; i < mondayList.children.length; i++) {
mondayListArray.push(mondayList.children[i].textContent);
}
updateDOM();
}
// On Load
updateDOM();
// Position the span tags for doctor visit item
const icons = document.querySelectorAll(".father");
icons[1].style.left = "12.5rem";
html {
box-sizing: border-box;
}
:root {
/* Light Theme Default */
/* Main Colors */
--primary-color: rgb(255, 255, 255);
--primary-variant: #b9b9b9;
--secondary-color: #5c5c5c;
/* Text on Main Colors */
--on-primary: rgb(54, 54, 54);
--on-background: rgb(78, 78, 78);
--on-background-alt: rgba(253, 253, 253, 0.952);
/* Background */
--background: rgb(255, 255, 255);
/* Box Shadow */
--box-shadow: 0 5px 20px 1px rgba(54, 54, 54, 0.5);
}
[data-theme="dark"] {
--primary-color: rgb(39, 39, 39);
--primary-variant: #777777;
--secondary-color: #e4e4e4;
--on-primary: rgb(173, 173, 173);
--on-background: rgba(255, 255, 255, 0.9);
--on-background-alt: rgba(0, 0, 0, 0.7);
--background: #202020;
}
body {
margin: 0;
color: var(--on-primary);
background-color:var(--primary-color);
font-family: 'Quicksand', sans-serif;
}
.slider.round::before {
border-radius: 50%;
}
.main-title {
font-size: 3rem;
color: var(--on-background);
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.main-container {
margin: 20px;
}
.days-list {
display: flex;
flex-direction:column;
}
/* Parent div container */
#Mondaycontent {
display: flex;
flex-direction: column;
}
#Mondaycontent .father {
position: relative;
left: 3rem;
width: 5rem;
margin-bottom: .5rem;
}
#Mondaycontent .father:last-child {
left: 12.5rem;
}
/* rows / poulation */
.day-row,.populating-btns {
margin: 10px 10px;
background-color: rgba(95, 95, 95, 0.4);
border-radius: 3px;
display: flex;
overflow-x: hidden;
flex-wrap: wrap;
}
.dayFunction {
align-content: center;
justify-content: center;
margin-top: auto;
margin-bottom: auto;
}
.Flex-right {
display: flex;
float: right;
}
.Monday-row .header,
.Monday-row .over {
background-color: var( --on-primary);
}
.hidden {
display: none;
}
.day-item {
margin: 10px;
padding: 10px;
height: fit-content;
background-color:var(--secondary-color);
color: var(--primary-color);
border-radius: 3px;
line-height: 1.5rem;
letter-spacing: 1px;
cursor: pointer;
transition: 1s;
}
.day-item:focus {
outline: none;
background-color: white;
color: black;
}
/* Add Button Group */
.add-btns {
display: flex;
justify-content: space-between;
}
.add-btn {
margin: 10px;
padding: 5px 10px;
display: flex;
align-items: center;
cursor: pointer;
width: fit-content;
border-radius: 5px;
transition: all 0.3s ease-in;
user-select: none;
}
.add-task {
margin: 10px;
padding: 5px 10px;
display: flex;
align-items: center;
cursor: pointer;
width: fit-content;
border-radius: 5px;
transition: all 0.3s ease-in;
user-select: none;
background-color:var(--on-primary);
color:var(--on-background-alt);
}
.add-btn,.add-task:hover {
background-color: rgba(255, 255, 255, 0.9);
color: black;
}
.add-btn:active {
transform: scale(0.97);
}
.add-btn-extend {
margin: 10px;
padding: 10px 40px 10px 40px;
display: flex;
align-items: center;
cursor: pointer;
border-radius: 5px;
transition: all 0.5s ease-in;
user-select: none;
background-color: rgba(12, 178, 207, 0.603);
}
.add-btn-extend:hover {
background-color: rgba(255, 255, 255, 0.9);
color: black;
}
.solidOnClick , .solidOnClickDelete {
margin: 10px;
padding: 5px 10px;
align-items: center;
cursor: pointer;
width: fit-content;
border-radius: 5px;
transition: all 0.3s ease-in;
user-select: none;
background-color: var(--primary-variant);
}
.solidonclick:hover{
transition: all 0.5s ease-in;
filter: brightness(95%);
color: rgb(0, 0, 0);
background-color: rgba(228, 228, 228, 0.842);
}
.father {
display: flex;
justify-content: space-between;
}
.fa-check-circle {
color: green;
}
.fa-times-circle {
color: red;
}
.hidden {
display: none;
}
<!DOCTYPE html>
<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>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.1/css/all.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="day-row Monday-row">
<div id="Mondaycontent">
<ul id="mondaylist" class="drag-item-list Flex-right" ondrop="drop(event)" ondragover="dropin(event)"
ondragenter="dragenter(0)">
</ul>
</div>
</div>
<!--Add Task To Li Later showInputBox()-->
<div class="add-container">
<div class="add-item" contenteditable="true"></div>
</div>
</div>
<!-- Include external JS Script at body close or within <head> -->
<script src="js.js"></script>
</body>
</html>

Selecting an element by the class name after insertAdjacentHTML

So when I click my start button, this function is working and I can see it
const displayFirstQuestion = () => {
main.insertAdjacentHTML("afterbegin",
`<div class="question-container">
<h2 class="question-tag">QUESTION 1</h2>
<h3 class="question">
What is the keyword to define a variable that can be modified?
</h3>
<div class="choices">
<p class="choice">A. Function</p>
<p class="choice">B. Const</p>
<p class="choice correct">C. Let</p>
<p class="choice">D. Var</p>
</div>
Next Question >>
</div>` );
};
So I want to select the element with 'correct' classname but it doesn't work. When I print it to the console, it says 'null' basically.
document.querySelector('.correct') // this is null
I tried to put the selector after inserting Html and other different places. It always says null.
Here is the codepen link:
https://codepen.io/raskolnikovcykakekw/pen/mdrvVqX
I just tried you code on browser console and it worked. I just had to close the template string in the 2nd arg of insertAdjacentHTML. Can you provide more info?
Update
Ok, I see. The problem is you are querying and registering events on elements when they aren't in the DOM yet. So, I'd suggest to:
Wrap the loop for registering .choice event listeners in a function and call it right after call displayFirstQuestion;
Query .correct and .nextButton inside answering function.
Something like this:
"use strict";
const main = document.querySelector(".main");
const container = document.querySelector(".container");
const startButton = document.querySelector(".start-button");
const questionContainer = document.querySelector(".question-container");
const choice = [...document.querySelectorAll(".choice")];
const correct = document.querySelector(".correct");
const nextButton = document.querySelector(".next-button");
const endingContanier = document.querySelector(".ending");
////////////////----------------------//////////////---------SELECTING QUESTIONS ---------//////
const displayFirstQuestion = () => {
main.insertAdjacentHTML(
"afterbegin",
`<div class="question-container">
<h2 class="question-tag">QUESTION 1</h2>
<h3 class="question">
What is the keyword to define a variable that can be modified?
</h3>
<div class="choices">
<p class="choice">A. Function</p>
<p class="choice">B. Const</p>
<p class="choice correct">C. Let</p>
<p class="choice">D. Var</p>
</div>
Next Question >>
</div>`
);
};
startButton.addEventListener("click", () => {
container.style.animation = "hidden 1s forwards";
setTimeout(() => {
container.remove();
}, 500);
setTimeout(displayFirstQuestion(), 501);
setTimeout(registerEventListeners(), 600);
});
//////////////////////////////////
const answering = function (element) {
const correct = document.querySelector(".correct");
if (!element.target.classList.contains("correct")) {
element.target.style.background = "red";
correct.style.background = "green";
} else {
correct.style.background = "green";
}
setTimeout(() => {
const nextButton = document.querySelector(".next-button");
nextButton.style.animation = "come-out 0.5s ease";
nextButton.style.display = "inline";
}, 300);
choice.forEach((e) => e.removeEventListener("click", answering));
};
const registerEventListeners = function() {
const choice = document.querySelectorAll(".choice");
choice.forEach(function (e) {
e.addEventListener("click", answering);
});
console.log(correct);
}
* {
margin: 0;
box-sizing: border-box;
}
body {
font-family: "Source Code Pro", monospace;
background: rgba(0, 0, 0, 0.685);
}
a {
text-decoration: none;
color: white;
}
h2 {
background: #323330;
padding: 0.5rem;
border: 1px solid #323330;
border-radius: 10px;
margin-bottom: 30px;
}
.container {
color: white;
display: flex;
flex-direction: column;
align-items: center;
margin: 15rem 0 0 0;
animation: come-out 1s forwards;
}
.start-button {
font-family: "Source Code Pro", monospace;
font-weight: 700;
width: 250px;
height: 55px;
font-size: 1.6rem;
color: #323330;
background: rgb(240, 219, 79);
margin: 2rem;
cursor: pointer;
border-bottom: 5px solid rgb(211, 191, 59);
border-left: 5px solid rgb(211, 191, 59);
border-right: 5px solid rgb(211, 191, 59);
border-top: 1px solid rgb(211, 191, 59);
transition: all 0.3s ease;
border-radius: 10px;
}
.start-button:hover {
color: rgb(240, 219, 79);
background: #323330;
border: 5px solid #323330;
}
.start-button:active {
transform: translate(5%);
}
.question-container {
color: white;
display: flex;
flex-direction: column;
align-items: center;
margin: 5rem 0 0 0;
line-height: 3rem;
font-size: 1.1rem;
animation: come-out 1s forwards;
}
.question {
margin: 0 0 3% 0;
text-align: center;
}
.choices {
flex-direction: column;
}
.choice {
cursor: pointer;
padding: 0 10px 0 10px;
margin-bottom: 10%;
background: rgba(0, 0, 0, 0.432);
border: 1px solid black;
border-radius: 12px;
box-shadow: 1px 1px 6px black;
transition: all 0.5s ease;
text-align: center;
}
.choice:hover {
background: rgba(0, 0, 0, 0.232);
}
.choice:active {
background: rgba(240, 218, 79, 0.229);
transform: translate(5%);
}
.choice-align-left {
text-align: left;
}
.next-button {
position: absolute;
top: 65%;
font-size: 20px;
height: 8vh;
font-family: "Source Code Pro", monospace;
color: white;
cursor: pointer;
margin-right: 15%;
background: rgba(0, 0, 0, 0.432);
border: 1px solid black;
border-radius: 5px;
box-shadow: 1px 1px 6px black;
align-self: flex-end;
display: none;
transition: all 0.5s ease;
}
.next-button:hover {
background: rgba(0, 0, 0, 0.232);
}
.next-button:active {
transform: translate(5%);
}
.back-button {
height: 3rem;
width: 20rem;
}
#keyframes hidden {
0% {
opacity: 1;
}
100% {
display: none;
opacity: 0;
}
}
#keyframes come-out {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.q2-green {
color: rgba(86, 221, 86, 0.596);
}
.q2-yellow {
color: yellow;
}
<body>
<main class="main">
<div class="container">
<h1>
WELCOME TO
<img src="logo.png" alt="js-logo" width="50px" height="50px" /> QUIZ
</h1>
<button class="start-button">LET'S START</button>
</div>
</main>
<script src="script.js"></script>
</body>
Then you can clean up a bit some code.

Categories