I'm pretty new to JavaScript and I'm trying to make the range slider in my Etch-a-Sketch project work, so that its value (i.e 8x8 - 64x64 = grid size) corresponds with the total number of div's inside my grid-container (.square). The value gets logged into the console, but I can't figure out how to change the total number of squares dynamically according to the sliders value. If I hardcode the value in makeRows(), the grid(lines) show up properly.
I think I'm doing something wrong with scoping and/or passing the correct parameters..? Can anyone give me a hand please?
Codepen:
https://codepen.io/Mein-Hirsch/pen/abKLzrV
const gridContainer = document.getElementById("grid-container");
// const colors = ["#e74c3c", "#8e44ad", "#3498db", "#e67e22", "#2ecc71"];
const range = document.getElementById("range"); //input Id
const rangeValue = document.getElementById("rangeValue");
let strToNum;
function makeRows(rows, cols) {
gridContainer.style.setProperty("--grid-rows", rows);
gridContainer.style.setProperty("--grid-cols", cols);
for (i = 0; i < rows * cols; i++) {
let cell = document.createElement("div");
gridContainer.appendChild(cell).className = "square";
}
}
makeRows(32, 32);
function sliderValue() {
let strToNum = parseInt(range.value);
console.log(strToNum);
return strToNum;
}
range.addEventListener("input", sliderValue);
Screenshot
JS Code
Thank you guys!
You just have to call your function with the correct parameters.
You don't have to set a variable, +x is the same as parseInt(x).
Also, don't forget to empty the grid before adding the new elements.
const gridContainer = document.getElementById("grid-container");
// const colors = ["#e74c3c", "#8e44ad", "#3498db", "#e67e22", "#2ecc71"];
const range = document.getElementById("range");
const rangeValue = document.getElementById("rangeValue");
function makeRows(rows, cols) {
gridContainer.innerHTML = "";
gridContainer.style.setProperty("--grid-rows", rows);
gridContainer.style.setProperty("--grid-cols", cols);
for (i = 0; i < rows * cols; i++) {
let cell = document.createElement("div");
gridContainer.appendChild(cell).className = "square";
}
}
makeRows(32, 32);
function sliderValue() {
makeRows(+range.value, +range.value);
}
range.addEventListener("input", sliderValue);
/* Basic sytling-----------------------------> */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--grid-cols: 1;
--grid-rows: 1;
}
body {
width: 100vw;
height: 100vh;
font-family: "Roboto", sans-serif;
display: flex;
flex-direction: column;
background-color: #2c2f36;
color: white;
}
main {
display: flex;
justify-content: center;
}
h1 {
font-size: 3.5rem;
text-align: center;
margin-top: 3rem;
}
.main-container {
width: 900px;
display: flex;
justify-content: space-evenly;
align-items: center;
margin-top: 5rem;
}
/* Settings-Container Styling -------------------------> */
.settings {
width: 350px;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
padding: 2rem;
}
#color-picker {
margin: 1rem 0 2rem 0;
width: 190.94px;
height: 46px;
cursor: pointer;
padding: 0;
}
input[type="color"]:first-child {
padding: 0;
margin: 0;
border: none;
box-shadow: none;
border-radius: 100px;
background: none;
margin-bottom: 20px;
}
input[type="color"]:hover {
transform: scale(1.03);
}
input[type="color"]::-webkit-color-swatch-wrapper {
padding: 0;
}
input[type="color"]::-webkit-color-swatch {
border: none;
}
.settings button {
width: 190.94px;
margin-bottom: 2rem;
font-size: 1.2rem;
padding: 0.75rem 0.75rem;
border-style: none;
cursor: pointer;
color: #fdfdfd;
background-color: #3c3f46;
box-shadow: 5px 5px 15px 5px rgba(0, 0, 0, 0.15);
}
.settings button:hover {
background-color: #494c55;
}
/* Grid Container Styling -------------------------------> */
#grid-container {
width: 500px;
height: 500px;
background-color: #fdfdfd;
box-shadow: 5px 5px 15px 5px rgba(0, 0, 0, 0.4);
display: grid;
grid-template-rows: repeat(var(--grid-rows), 1fr);
grid-template-columns: repeat(var(--grid-cols), 1fr);
/* grid-template-columns: repeat(8, 1fr);
grid-template-rows: repeat(8, 1fr); */
box-sizing: inherit;
overflow: hidden;
}
.square {
border: 1px solid rgb(224, 219, 219);
}
/* Slider Styling ---------------------------------------> */
.slider {
width: 190.94px;
height: 60px;
padding: 30px;
padding-left: 40px;
background-color: #2c2f36;
display: flex;
align-items: center;
justify-content: center;
}
.slider p {
font-size: 1rem;
font-weight: 400;
padding-left: 20px;
color: #fdfdfd;
}
.slider input[type="range"] {
-webkit-appearance: none !important;
height: 2px;
background: #5c606b;
border: none;
outline: none;
}
.slider input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none !important;
width: 20px;
height: 20px;
background: #ca4d4d;
border: 1px solid black;
border-radius: 50%;
cursor: pointer;
}
/* Footer Styling ------------------------------------------------> */
footer {
color: #fdfdfd;
display: flex;
justify-content: center;
padding: 1rem;
position: relative;
}
.footer-content {
display: flex;
justify-content: center;
position: fixed;
bottom: 0px;
margin-bottom: 2rem;
}
.fa-github {
color: #151516;
font-size: 24px;
transition: transform 0.3s ease-in-out;
margin-left: 0.6rem;
}
.fa-github:hover {
transform: rotate(360deg) scale(1.2);
}
<!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" />
<link rel="stylesheet" href="./style.css" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<script src="https://kit.fontawesome.com/4c536a6bd5.js" crossorigin="anonymous"></script>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght#400;700&display=swap" rel="stylesheet" />
<title>Etchy</title>
</head>
<body>
<h1>Etch a Sketch</h1>
<main>
<div class="main-container">
<div class="settings">
<input id="color-picker" type="color" />
<button id="color-mode">Color mode</button>
<button id="rainbow-mode">Rainbow mode</button>
<button id="eraser">Eraser</button>
<button id="clear">Reset</button>
<div class="slider">
<input type="range" min="8" max="64" value="100" id="range" oninput="rangeValue.innerText = this.value" />
<p id="rangeValue">32</p>
</div>
</div>
<div id="grid-container" class="container"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
Related
i dont' get why my javascript code works differently despite it looks like same to me. I am a beginner and I tried to figure out what is wrong and I couldn't. In one method which I have commented the code works in a way it should work while in other it looks like the code is broken. It works in way it shouldn't and I couldn't figure out why it is happening.
let smallCups = document.querySelectorAll(".cup-small")
let liters = document.getElementById("liters")
let percentage = document.getElementById("percentage")
let remained = document.getElementById("remained")
// smallCups.forEach(function (cup, idx) {
// cup.addEventListener("click", function () {
// highLightCups(idx)
// })
// })
// function highLightCups(idx) {
// if (smallCups[idx].classList.contains("full")) {
// idx--
// }
// smallCups.forEach(function (cup, idx2) {
// if (idx2 <= idx) {
// cup.classList.add("full")
// } else {
// cup.classList.remove("full")
// }
// })
// }
smallCups.forEach(function(cup, idx) {
cup.addEventListener("click", function() {
if (smallCups[idx].classList.contains("full")) {
idx--
}
smallCups.forEach(function(cup, idx2) {
if (idx2 <= idx) {
cup.classList.add("full")
} else {
cup.classList.remove("full")
}
})
})
})
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--border-color: #144fc6;
--fill-color: #6ab3f8;
}
html {
font-size: 62.5%;
/* 1rem = 10px */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
font-size: 1.6rem;
font-family: "Poppins", sans-serif;
background-color: #3494e4;
display: flex;
flex-direction: column;
align-items: center;
color: #fff;
}
h1 {
margin: 10px 0 0;
}
h3 {
font-weight: 400;
margin: 10px 0;
}
.cup {
background-color: #fff;
border: 4px solid var(--border-color);
color: var(--border-color);
border-radius: 0 0 40px 40px;
height: 330px;
width: 150px;
margin: 30px 0;
display: flex;
flex-direction: column;
overflow: hidden;
}
.cup.cup-small {
height: 95px;
width: 50px;
border-radius: 0 0 15px 15px;
background-color: rgba(255, 255, 255, 0.9);
cursor: pointer;
font-size: 14px;
align-items: center;
justify-content: center;
text-align: center;
margin: 5px;
transition: .3s ease;
}
.cups {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
width: 280px;
}
.cup.cup-small.full {
background-color: var(--fill-color);
color: #fff;
}
.remained {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
flex: 1;
transition: .3s ease;
}
.remained span {
font-size: 20px;
font-weight: 600;
}
.remained small {
font-size: 12px;
}
.percentage {
background-color: var(--fill-color);
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 3rem;
height: 0;
transition: .3s ease;
}
.text {
text-align: center;
margin: 0 0 5px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght#100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
<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>
<h2>drink water</h2>
<h3>goal : 2 liter</h3>
<div class="cup">
<div class="remained" id="remainded">
<span id="liters">1.5l</span>
<span>remained</span>
</div>
<div class="percentage" id="percentage">20%</div>
</div>
<p class="text">select how many glasses of water that you have drank</p>
<div class="cups">
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
</div>
<script src="https://kit.fontawesome.com/d48313b36e.js" crossorigin="anonymous"></script>
<script src="main.js"></script>
</body>
</html>
The problem is idx.
In the commented version idx is passed to the function and is passed by value. A local variable (also called idx) is created. Any changes to the value of idx are not persisted between clicks.
In your version the variable idx is captured in a closure by the event handler . Each time the click handler runs it gets the value of the captured variable idx which is being updated by the code. The next time the handler runs it uses the updated value of idx and not the original value.
To fix your version you will have to create a copy of idx e.g. let index = idx; and use the variable index inside the click handler to make sure the value of idx never changes!
let smallCups = document.querySelectorAll(".cup-small")
let liters = document.getElementById("liters")
let percentage = document.getElementById("percentage")
let remained = document.getElementById("remained")
smallCups.forEach(function(cup, idx) {
cup.addEventListener("click", function() {
// use original value of idx but do not update it!
let index = idx;
if (smallCups[index].classList.contains("full")) {
index--
}
smallCups.forEach(function(cup, idx2) {
if (idx2 <= index) {
cup.classList.add("full")
} else {
cup.classList.remove("full")
}
})
})
})
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--border-color: #144fc6;
--fill-color: #6ab3f8;
}
html {
font-size: 62.5%;
/* 1rem = 10px */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
font-size: 1.6rem;
font-family: "Poppins", sans-serif;
background-color: #3494e4;
display: flex;
flex-direction: column;
align-items: center;
color: #fff;
}
h1 {
margin: 10px 0 0;
}
h3 {
font-weight: 400;
margin: 10px 0;
}
.cup {
background-color: #fff;
border: 4px solid var(--border-color);
color: var(--border-color);
border-radius: 0 0 40px 40px;
height: 330px;
width: 150px;
margin: 30px 0;
display: flex;
flex-direction: column;
overflow: hidden;
}
.cup.cup-small {
height: 95px;
width: 50px;
border-radius: 0 0 15px 15px;
background-color: rgba(255, 255, 255, 0.9);
cursor: pointer;
font-size: 14px;
align-items: center;
justify-content: center;
text-align: center;
margin: 5px;
transition: .3s ease;
}
.cups {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
width: 280px;
}
.cup.cup-small.full {
background-color: var(--fill-color);
color: #fff;
}
.remained {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
flex: 1;
transition: .3s ease;
}
.remained span {
font-size: 20px;
font-weight: 600;
}
.remained small {
font-size: 12px;
}
.percentage {
background-color: var(--fill-color);
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 3rem;
height: 0;
transition: .3s ease;
}
.text {
text-align: center;
margin: 0 0 5px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght#100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
<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>
<h2>drink water</h2>
<h3>goal : 2 liter</h3>
<div class="cup">
<div class="remained" id="remainded">
<span id="liters">1.5l</span>
<span>remained</span>
</div>
<div class="percentage" id="percentage">20%</div>
</div>
<p class="text">select how many glasses of water that you have drank</p>
<div class="cups">
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
<div class="cup cup-small">250ml</div>
</div>
<script src="https://kit.fontawesome.com/d48313b36e.js" crossorigin="anonymous"></script>
<script src="main.js"></script>
</body>
</html>
is there an easy fix to separate the volume icon from the volume slider? I have the volume icon change depending on the slider value but it feels janky because the size of the icon changes and pushes everything. I think you can c/p the code on replit and see the problem with the volume slider.
I tried aligning it to the right or changing the position using transform but it doesn't seem to fix the problem.
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<link href="style.css" rel="stylesheet" type="text/css" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
</head>
<body>
<div class="video-player">
<video id="myVideo" poster="Poke_Ball.png">
<source src="https://www.youtube.com/watch?v=Y3xgmGSnzlU" class="video">
</video>
<div class="player-controls">
<div class="video-progress">
<div class="video-progress-filled"></div>
</div>
<button id="btnPlay"><i class="fa fa-play-circle-o"></i></button>
<button id="btnPause" class="hidden"><i class="fa fa-pause-circle-o"></i></button>
<button id="volumeNone" class="hidden"><i class="fa fa-volume-off"></i></button>
<button id="volumeLow" class="hidden"><i class="fa fa-volume-down"></i></button>
<button id="volumeHigh"><i class="fa fa-volume-up"></i></button>
<input type="range" class="volume" min="0" max="1" step="0.01" value=".5"/>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
.hidden {
display: none;
}
.video-player {
max-width: 100%;
position: relative;
overflow: hidden;
}
.player-controls {
display: flex;
position: absolute;
bottom: 0;
width: 100%;
transform: translateY(100%) translateY(-5px);
transition: 0.3s;
flex-wrap: wrap;
background: rgba(0, 0, 0, 0.6);
}
.video-player:hover .player-controls {
transform: translateY(0);
}
.video-progress {
position: relative;
display: flex;
width: 100%;
height: 5px;
transition: 0.3s;
background: rgba(0, 0, 0, 0.6);
cursor: pointer;
}
.video-progress-filled {
width: 0;
background: orangered;
}
.video-player:hover .video-progress {
height: 13px;
}
input[type="range"] {
-webkit-appearance: none;
background: transparent;
margin: 0;
width: 7%;
padding: 0 10px;
}
input[type="range"]:focus {
outline: none;
}
input[type="range"]::-webkit-slider-runnable-track {
width: 5%;
height: 10px;
cursor: pointer;
background: white;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
height: 10px;
width: 13px;
background: orangered;
cursor: pointer;
}
#timeOut{
font-family: monospace;
font-size: 120%;
padding: 18px;
color: white;
border: none;
background: none;
}
#btnPlay,#btnPause,#volumeNone,#volumeLow,#volumeHigh {
font-size: 200%;
padding: 10px;
color: white;
border: none;
background: none;
}
#btnPlay:hover,#btnPause:hover,#volumeNone:hover,#volumeLow:hover,#volumeHigh:hover {
transition: all 0.1s ease;
color: orangered;
}
const volume = document.querySelector('.volume');
const volumeNone = document.getElementById("volumeNone");
const volumeLow = document.getElementById("volumeLow");
const volumeHigh = document.getElementById("volumeHigh");
const myVideo = document.getElementById("myVideo");
const btnPlay = document.getElementById("btnPlay");
const btnPause = document.getElementById("btnPause");
btnPlay.addEventListener("click", vidPlay);
btnPause.addEventListener("click", vidPause);
volume.addEventListener('mousemove', (e)=> {
myVideo.volume = e.target.value;
if(myVideo.volume === 0){
volumeNone.classList.remove("hidden");
volumeLow.classList.add("hidden");
volumeHigh.classList.add("hidden");
}
else if(myVideo.volume < .5 && myVideo.volume > .1){
volumeNone.classList.add("hidden");
volumeLow.classList.remove("hidden");
volumeHigh.classList.add("hidden");
}
else if(myVideo.volume > .5) {
volumeNone.classList.add("hidden");
volumeLow.classList.add("hidden");
volumeHigh.classList.remove("hidden");
}
})
function vidPlay() {
btnPlay.classList.add("hidden");
btnPause.classList.remove("hidden");
myVideo.play();
}
function vidPause() {
btnPlay.classList.remove("hidden");
btnPause.classList.add("hidden");
myVideo.pause();
}
is there an easy fix to separate the volume icon from the volume slider?
- Simply removing the code
You can remove the code that makes the volume icon synchronized with the volume slider in the first place.
const volume = document.querySelector('.volume');
const volumeNone = document.getElementById("volumeNone");
const volumeLow = document.getElementById("volumeLow");
const volumeHigh = document.getElementById("volumeHigh");
const myVideo = document.getElementById("myVideo");
const btnPlay = document.getElementById("btnPlay");
const btnPause = document.getElementById("btnPause");
btnPlay.addEventListener("click", vidPlay);
btnPause.addEventListener("click", vidPause);
/* volume.addEventListener('mousemove', (e)=> {
myVideo.volume = e.target.value;
if(myVideo.volume === 0){
volumeNone.classList.remove("hidden");
volumeLow.classList.add("hidden");
volumeHigh.classList.add("hidden");
}
else if(myVideo.volume < .5 && myVideo.volume > .1){
volumeNone.classList.add("hidden");
volumeLow.classList.remove("hidden");
volumeHigh.classList.add("hidden");
}
else if(myVideo.volume > .5) {
volumeNone.classList.add("hidden");
volumeLow.classList.add("hidden");
volumeHigh.classList.remove("hidden");
}
})
*/
function vidPlay() {
btnPlay.classList.add("hidden");
btnPause.classList.remove("hidden");
myVideo.play();
}
function vidPause() {
btnPlay.classList.remove("hidden");
btnPause.classList.add("hidden");
myVideo.pause();
}
.hidden {
display: none;
}
.video-player {
max-width: 100%;
position: relative;
overflow: hidden;
}
.player-controls {
display: flex;
position: absolute;
bottom: 0;
width: 100%;
transform: translateY(100%) translateY(-5px);
transition: 0.3s;
flex-wrap: wrap;
background: rgba(0, 0, 0, 0.6);
}
.video-player:hover .player-controls {
transform: translateY(0);
}
.video-progress {
position: relative;
display: flex;
width: 100%;
height: 5px;
transition: 0.3s;
background: rgba(0, 0, 0, 0.6);
cursor: pointer;
}
.video-progress-filled {
width: 0;
background: orangered;
}
.video-player:hover .video-progress {
height: 13px;
}
input[type="range"] {
-webkit-appearance: none;
background: transparent;
margin: 0;
width: 7%;
padding: 0 10px;
}
input[type="range"]:focus {
outline: none;
}
input[type="range"]::-webkit-slider-runnable-track {
width: 5%;
height: 10px;
cursor: pointer;
background: white;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
height: 10px;
width: 13px;
background: orangered;
cursor: pointer;
}
#timeOut{
font-family: monospace;
font-size: 120%;
padding: 18px;
color: white;
border: none;
background: none;
}
#btnPlay,#btnPause,#volumeNone,#volumeLow,#volumeHigh {
font-size: 200%;
padding: 10px;
color: white;
border: none;
background: none;
}
#btnPlay:hover,#btnPause:hover,#volumeNone:hover,#volumeLow:hover,#volumeHigh:hover {
transition: all 0.1s ease;
color: orangered;
}
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<link href="style.css" rel="stylesheet" type="text/css" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
</head>
<body>
<div class="video-player">
<video id="myVideo" poster="Poke_Ball.png">
<source src="https://www.youtube.com/watch?v=Y3xgmGSnzlU" class="video">
</video>
<div class="player-controls">
<div class="video-progress">
<div class="video-progress-filled"></div>
</div>
<button id="btnPlay"><i class="fa fa-play-circle-o"></i></button>
<button id="btnPause" class="hidden"><i class="fa fa-pause-circle-o"></i></button>
<button id="volumeNone" class="hidden"><i class="fa fa-volume-off"></i></button>
<button id="volumeLow" class="hidden"><i class="fa fa-volume-down"></i></button>
<button id="volumeHigh"><i class="fa fa-volume-up"></i></button>
<input type="range" class="volume" min="0" max="1" step="0.01" value=".5"/>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
- Quick and easy fix instead of giving up on the idea
If the only reason you don't want to use this code is because it "feels janky", I fixed it by adding `min-width: 60px;` to `#btnPlay,#btnPause,#volumeNone,#volumeLow,#volumeHigh`. The problem was that the `volumeHigh`'s width was larger than `volumeLow` and `volumeNone`'s. fixing all the icon's width at a minimum of 60px solved the problem. `width: 60px` will also work.
const volume = document.querySelector('.volume');
const volumeNone = document.getElementById("volumeNone");
const volumeLow = document.getElementById("volumeLow");
const volumeHigh = document.getElementById("volumeHigh");
const myVideo = document.getElementById("myVideo");
const btnPlay = document.getElementById("btnPlay");
const btnPause = document.getElementById("btnPause");
btnPlay.addEventListener("click", vidPlay);
btnPause.addEventListener("click", vidPause);
volume.addEventListener('mousemove', (e)=> {
myVideo.volume = e.target.value;
if(myVideo.volume === 0){
volumeNone.classList.remove("hidden");
volumeLow.classList.add("hidden");
volumeHigh.classList.add("hidden");
}
else if(myVideo.volume < .5 && myVideo.volume > .1){
volumeNone.classList.add("hidden");
volumeLow.classList.remove("hidden");
volumeHigh.classList.add("hidden");
}
else if(myVideo.volume > .5) {
volumeNone.classList.add("hidden");
volumeLow.classList.add("hidden");
volumeHigh.classList.remove("hidden");
}
})
function vidPlay() {
btnPlay.classList.add("hidden");
btnPause.classList.remove("hidden");
myVideo.play();
}
function vidPause() {
btnPlay.classList.remove("hidden");
btnPause.classList.add("hidden");
myVideo.pause();
}
.hidden {
display: none;
}
.video-player {
max-width: 100%;
position: relative;
overflow: hidden;
}
.player-controls {
display: flex;
position: absolute;
bottom: 0;
width: 100%;
transform: translateY(100%) translateY(-5px);
transition: 0.3s;
flex-wrap: wrap;
background: rgba(0, 0, 0, 0.6);
}
.video-player:hover .player-controls {
transform: translateY(0);
}
.video-progress {
position: relative;
display: flex;
width: 100%;
height: 5px;
transition: 0.3s;
background: rgba(0, 0, 0, 0.6);
cursor: pointer;
}
.video-progress-filled {
width: 0;
background: orangered;
}
.video-player:hover .video-progress {
height: 13px;
}
input[type="range"] {
-webkit-appearance: none;
background: transparent;
margin: 0;
width: 7%;
padding: 0 10px;
}
input[type="range"]:focus {
outline: none;
}
input[type="range"]::-webkit-slider-runnable-track {
width: 5%;
height: 10px;
cursor: pointer;
background: white;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
height: 10px;
width: 13px;
background: orangered;
cursor: pointer;
}
#timeOut{
font-family: monospace;
font-size: 120%;
padding: 18px;
color: white;
border: none;
background: none;
}
#btnPlay,#btnPause,#volumeNone,#volumeLow,#volumeHigh {
font-size: 200%;
padding: 10px;
color: white;
border: none;
background: none;
min-width: 60px;
}
#btnPlay:hover,#btnPause:hover,#volumeNone:hover,#volumeLow:hover,#volumeHigh:hover {
transition: all 0.1s ease;
color: orangered;
}
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<link href="style.css" rel="stylesheet" type="text/css" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
</head>
<body>
<div class="video-player">
<video id="myVideo" poster="Poke_Ball.png">
<source src="https://www.youtube.com/watch?v=Y3xgmGSnzlU" class="video">
</video>
<div class="player-controls">
<div class="video-progress">
<div class="video-progress-filled"></div>
</div>
<button id="btnPlay"><i class="fa fa-play-circle-o"></i></button>
<button id="btnPause" class="hidden"><i class="fa fa-pause-circle-o"></i></button>
<button id="volumeNone" class="hidden"><i class="fa fa-volume-off"></i></button>
<button id="volumeLow" class="hidden"><i class="fa fa-volume-down"></i></button>
<button id="volumeHigh"><i class="fa fa-volume-up"></i></button>
<input type="range" class="volume" min="0" max="1" step="0.01" value=".5"/>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
I'm not sure if this is different in a video player for whatever reason but when facing issues like that in the past I usually will wrap the icon in some kind of container that is big enough to accommodate the biggest icon. It needs to have either static dimensions or dimensions that are informed by something other than its contents.
Then you can either give it position relative and center the icons absolutely, or (and this is what I recommend) you can just use flexbox to center the icon.
Here is a Svelte Repl with an example. If you don't know svelte don't worry just know I'm switching between a 24x24 icon and a 34x34 icon and am using the button as the container. The styles are in a style tag at the bottom.
https://svelte.dev/repl/34a316c3169248ce84b18972ab4953f5?version=3.47.0
I have been trying to create a single div with its respective children but the loop creates all the DIVs related to the API but populates all the IMG inside the first div. What I'm trying to achieve is creating this through a loop:
<div id="box" class="box">
<span class="title"></span>
<a href="#link from image">
<img src="#url goes here" />
</a>
</div>
So later I can create cards individually in CSS to organize each thumbnail as a link as well as the title on top and wrapped inside the image.
The JS I have so far for this is as follows:
const form = document.querySelector('#buscarPosts')
/* document.addEventListener('load', async function(e) {
e.preventDefault();
const loadPage = await axios.get('https://api.devall.com.br/api/v1/post')
const loadFirst = (firsts) => {
for (let firstLoad of firsts) {
const div = document.createElement('DIV');
div.id = 'box';
div.classList.add('box');
const img = document.createElement('IMG');;
img.src = result.thumbnail;
img.classList.add('thumbnailClass')
const title = document.createElement('SPAN');
title.classList.add('title')
title.innerHTML = result.titulo;
document.querySelector("#container").append(div)
document.querySelector("#box").append(title);
document.querySelector("#box").append(img);
}
}
loadFirst(loadPage.data)
}) */
form.addEventListener('submit', async function(e){
e.preventDefault();
const searchValue = form.elements.search.value;
const res = await axios.get(`https://api.devall.com.br/api/v1/post?search=${searchValue}`)
addThumbnails(res.data);
})
const addThumbnails = (previews) => {
for (let result of previews) {
const box = document.createElement('DIV');
box.id = 'box';
box.classList.add('box');
const img = document.createElement('IMG');
img.src = result.thumbnail;
img.classList.add('thumbnailClass')
const title = document.createElement('SPAN');
title.classList.add('title')
title.innerHTML = result.titulo;
document.querySelector("#container").append(box)
document.querySelector("#box").append(title);
document.querySelector("#box").append(img);
}
}
* {
margin: 0;
padding: 0;
}
body {
background: url("../images/pexels-scott-webb-3255761.jpg");
filter: saturate(150%);
background-size: cover;
}
fieldset {
margin: 0;
padding: 0;
-webkit-margin-start: 0;
-webkit-margin-end: 0;
-webkit-padding-before: 0;
-webkit-padding-start: 0;
-webkit-padding-end: 0;
-webkit-padding-after: 0;
border: 0;
}
.s006 {
display: -ms-flexbox;
display: flex;
-ms-flex-pack: center;
justify-content: center;
-ms-flex-align: center;
align-items:flex-start;
font-family: 'Poppins', sans-serif;
padding-top: 50px;
margin-bottom: 50px;
}
.s006 form {
width: 100%;
max-width: 790px;
}
.s006 form legend {
font-size: 36px;
color: #fff;
font-weight: 800;
text-align: center;
margin-bottom: 30px;
}
.s006 form .inner-form .input-field {
height: 50px;
width: 100%;
position: relative;
}
.s006 form .inner-form .input-field input {
height: 100%;
width: 100%;
background: transparent;
border: 0;
background: #fff;
display: block;
width: 100%;
padding: 10px 32px 10px 30px;
font-size: 18px;
color: #666;
border-radius: 34px;
}
.s006 form .inner-form .input-field input:hover, .s006 form .inner-form .input-field input:focus {
box-shadow: none;
outline: 0;
}
.s006 form .inner-form .input-field .btn-search {
width: 70px;
display: flex;
-ms-flex-align: center;
align-items: center;
position: absolute;
right: 0;
height: 100%;
background: transparent;
border: 0;
padding: 0;
cursor: pointer;
justify-content: center;
align-items: center;
}
.s006 form .inner-form .input-field .btn-search svg {
fill: #ccc;
width: 30px;
height: 30px;
transition: all .2s ease-out, color .2s ease-out;
}
.s006 form .inner-form .input-field .btn-search:hover, .s006 form .inner-form .input-field .btn-search:focus {
outline: 0;
box-shadow: none;
}
.s006 form .inner-form .input-field .btn-search:hover svg, .s006 form .inner-form .input-field .btn-search:focus svg {
fill: #666;
}
.container {
max-width: 1520px;
display: flex;
flex-flow: row wrap;
align-content: center;
justify-content: flex-start;
}
.thumbnailClass {
height: 200px;
padding: 18px;
opacity: 0.6;
text-align: center;
}
.thumbnailClass:before {
content:'';
display: table;
float:left;
padding-top:100%;
}
.thumbnailClass:hover {
background-color: rgba(255, 255, 255, 0.0);
opacity: 1;
transition: background-color 0.5s;
transition: opacity 0.5s;
}
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="https://fonts.googleapis.com/css?family=Poppins:400,800" rel="stylesheet" />
<link href="css/main.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div class="s006">
<form id="buscarPosts">
<fieldset>
<legend style="color: black;">/dev/All</legend>
<div class="inner-form">
<div class="input-field">
<button class="btn-search" type="submit">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
</svg>
</button>
<input id="search" type="text" placeholder="Search for a post"/>
</div>
</div>
</fieldset>
</form>
</div>
<post id="container" class="container">
</post>
</body>
<script src="js/main.js"></script>
</html>
The issue is, only the first DIV created is populated with all the images inside and what I want is, for every div a separated img like the first example I posted. Please help!
When you append an element to the document the element is being populated with closing tag. It is not open so you can add other elements inside it. To append element inside the box, just use box.append....
document.querySelector("#container").append(box)
box.append(title);
box.append(img);
I want to make the popup show when score is equal to 6. and then when you press the button the page should reload. But i can't seem to make it work. i tried the function with the if-statement but it doens't work. so i don't know what to do or how to do it. so i would enjoy it if someone could help me out :)
//Function for the dropdown content
function dropdownTips() {
document.getElementById("mydropdown").classList.toggle("show");
}
window.addEventListener("click", function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdowncontent");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
});
//the game
// Declares global variables
let score = 0,
cardToMatch = null;
// Calls `flipCard` on any click
window.addEventListener("click", flipCard);
// Defines the click listener
function flipCard(event) {
// Identifies the card where the click happened
const card = event.target.closest(".card");
// Ignores irrelevant/invalid clicks
if (!card || card.classList.contains("open")) {
return;
}
// A valid click always opens the card
card.classList.add("open");
// If this is the 1st card of 2, remember it
if (cardToMatch === null) {
cardToMatch = card;
} else {
// If it's the 2nd card, compare types
// If they match...
if (card.dataset.type === cardToMatch.dataset.type) {
// ...Increment score and show it in the DOM
updateScoreDisplay(++score);
}
// If they don't...
else {
// ...Flip both cards back over
setTimeout((first, second) => {
first.classList.remove("open");
second.classList.remove("open");
}, 3000, card, cardToMatch);
// Either way, next click will be the 1st of 2
}
cardToMatch = null;
}
}
function updateScoreDisplay(newScore) {
// Syncs the user-displayed value w/ score
const element = document.querySelector(".score span");
element.textContent = newScore;
}
// popup section
let popup = document.querySelector(".popup");
popup = function() {
if (score === 6) {
popup.style.display ="block";
console.log("hello");
}
}
* {
margin: 0;
padding: 0;
font-family: 'Lato', sans-serif;
}
header {
background-color:#00005e;
height: 50px;
position: relative;
}
header h1 {
color: white;
position: absolute;
top: 10%;
left: 38%;
right: 40%;
width: 355px;
}
/*The 'tips?' button and the drop down content*/
header button {
display: inline-flex;
position:absolute;
align-items: center;
right: 2%;
top: 15%;
bottom: 15%;
padding: 10px 20px;
font-size: 20px;
background-color:white;
color: #00005e;
border-radius: 10px;
cursor: pointer;
border-color: transparent;
}
header button:hover {
opacity: 80%;
}
.dropdowncontent {
display: none;
position: absolute;
right: 0%;
top: 100%;
background-color:#010169;
min-width: 160px;
max-width: 400px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.808);
border-bottom-left-radius: 20px;
z-index: 100;
}
.dropdowncontent li {
color: white;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.advise{
font-size: 19px;
}
.passwordtips {
font-size: 30px;
left: 20%;
}
.show {
display:block;
}
/*The link in the dropdowncontent*/
a {
text-decoration: underline;
color: white;
}
a:hover {
cursor: pointer;
}
/*The score counter*/
.score {
color: #01016e;
display: flex;
justify-content: center;
margin: 10px;
font-size: 30px;
}
/*The game section*/
.sectionOne {
max-width: 1100px;
height: 550px;
display: flex;
justify-content: space-around;
margin-top: 10px;
margin-left: auto;
margin-right: auto;
border-radius: 7px;
border-color: #00005e;
border-style: solid;
border-width: 5px;
position: relative;
}
/*The sections content*/
.wrapper {
width: 99%;
height: 100%;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 183px;
margin-top: 7px;
}
.card{
background-color: #01016e;
color: white;
margin: 10px 10px;
height: 150px;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
font-size: 0;
border-radius: 5px;
}
.card h2{
padding: 2px;
transform: scale(-1,1);
}
.card:hover {
cursor: pointer;
}
.open{
animation: flip .5s;
animation-fill-mode: forwards;
transform-style: preserve-3d;
}
#keyframes flip {
from {
background: #00005e;
font-size: 0;
}
to{
background: rgb(20, 73, 185);
font-size:17px;
transform: rotateY( 180deg );
}
}
/* pop up section */
.popup {
position: absolute;
background-color: white;
width: 700px;
height: 500px;
z-index: 100;
right: 50.5vh;
top: 14%;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.808);
border-radius: 8px;
display: none;
}
.congrats {
position: relative;
display: flex;
justify-content: center;
height: 40px;
top: 20%;
color: #00005e;
font-size: 40px;
}
.matches {
position: relative;
height: 40px;
top: 35%;
color: #00005e;
display: flex;
justify-content: center;
font-size: 30px;
}
.playAgain {
position: absolute;
height: 40px;
width: 150px;
top: 65%;
left: 40%;
cursor: pointer;
color: white;
background-color: #00005e;
border-style: none;
font-size: 20px;
border-radius: 5px;
}
/*The 'DID YOU KNOW' over the ticker*/
.facts {
display: flex;
justify-content: space-around;
margin-top: 15px;
font-size: 20px;
color: #00005e;
}
/*The facts ticker*/
.tcontainer {
max-width: 1100px;
margin-top: 20px;
overflow: hidden;
margin-left: auto;
margin-right: auto;
border-radius: 5px;
z-index: 1000;
}
.ticker-wrap {
width: 100%;
padding-left: 100%;
background-color: #00005e;
}
#keyframes ticker {
0% { transform: translate3d(0, 0, 0); }
100% { transform: translate3d(-100%, 0, 0); }
}
.ticker-move {
display: inline-block;
white-space: nowrap;
padding-right: 100%;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-name: ticker;
animation-duration: 55s;
}
.ticker-move:hover{
animation-play-state: paused;
}
.ticker-item{
display: inline-block;
padding-top: 5px;
padding-bottom: 2px;
padding-right: 3em;
color: white;
min-height: 40px;
font-size: 25px;
}
/*The pause button for the ticker*/
.pause {
display: flex;
justify-content: center;
margin-top: 10px;
}
.pausebutton {
padding: 5px;
border-radius: 3px;
background-color: #00005e;
color: white;
border-style: none;
cursor: pointer;
}
.pausebutton:hover {
background-color: #3c3b6e;
}
<!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">
<link rel="stylesheet" href="css/style.css">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Lato:wght#700&display=swap" rel="stylesheet">
<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon" />
<title>The Password Game</title>
</head>
<body>
<header>
<h1>THE PASSWORD GAME</h1>
<div class="dropdown">
<button onclick="dropdownTips()" class="dropbtn">TIPS?</button>
<div class="dropdowncontent" id="mydropdown" >
<ul>
<li class="passwordtips">Tips for making strong passwords: </li>
<li class="advise">1. Use 16 characters or more (use both uppercase and lowercase letters, number and symbols.)</li>
<li class="advise">2. Never use the same password twice.</li>
<li class="advise">3. Use a password manager.</li>
<li class="advise">4. Don't write your passwords down on paper.</li>
<li class="advise">5. Don't share your passwords with others.</li>
<li class="advise">6. Change your password after a breach.</li>
<li class="advise">7. Sign up for data breach notifications. (like haveibeenpwned.com).</li>
<li class="advise">8. Check your accounts regularly for any suspicious activity. </li>
</ul>
</div>
</div>
</header>
<div class="score">Score:<span> 0</span></div>
<section class="sectionOne">
<div class="wrapper" id="card-deck">
<div class="card" data-type="1"><h2>What information should you NEVER use in a password?</h2></div>
<div id="answerSix" class="card" data-type="6"><h2>1 log in</h2></div>
<div id="cardThree" class="card" data-type="3"><h2>When should you ALWAYS change your password?</h2></div>
<div id="anserFive" class="card" data-type="5"><h2>suspicious activity</h2></div>
<div id="cardTwo" class="card" data-type="2"><h2>Who is it okay to tell your password to?</h2></div>
<div id="answerFour" class="card" data-type="4"><h2>16</h2></div>
<div id="answerThree" class="card" data-type="3"><h2>After a data breach</h2></div>
<div id="answerTwo" class="card" data-type="2"><h2>No one</h2></div>
<div id="CardSix" class="card" data-type="6"><h2>For how many log ins is it okay to use the same password?</h2></div>
<div id="cardFour" class="card" data-type="4"><h2>How many characters should you AT LEAST use in a password?</h2></div>
<div class="card" data-card="firstSet" data-type="1"><h2>Name and Birthday</h2></div>
<div id="cardFive" class="card" data-type="5"><h2>What should you regularly look for in your accounts?</h2></div>
</div>
</section>
<section class="popup">
<h3 class="congrats">Congratulations!</h3>
<h3 class="matches">You got 6/6 matches</h3>
<button class="playAgain">Play again?</button>
</section>
<div class="facts">
<h2>DID YOU KNOW?</h2>
</div>
<div class="tcontainer"><div class="ticker-wrap"><div class="ticker-move">
<div class="ticker-item">There is a hacker attack every 39 seconds.</div>
<div class="ticker-item">90% of passwords can be cracked in less than 6 hours.</div>
<div class="ticker-item">80% of hacking related breaches are linked to insufficient passwords.</div>
<div class="ticker-item">59% use their name or birthday in their password.</div>
<div class="ticker-item">6.850.000 passwords are getting hacked each day.</div>
</div></div></div>
<div class="pause">
<p>Hold your mouse over to pause</p>
</div>
<script src="javascript/javascript.js" ></script>
</body>
</html>
you have this code which doesnt run when score is incremented
popup = function() {
if (score === 6) {
popup.style.display ="block";
console.log("hello");
}
}
so i've created a function to check the score like this
let popup = document.querySelector("#popup");
function showPopup() {
if (score === 6) {
popup.style.display ="block";
console.log("hello");
}
}
And call the showPopup function when score is added like this
if (card.dataset.type === cardToMatch.dataset.type) {
// ...Increment score and show it in the DOM
updateScoreDisplay(++score);
showPopup();
}
full code :
//Function for the dropdown content
let popup = document.querySelector("#popup");
function showPopup() {
if (score > 0) {
popup.style.display ="block";
console.log("hello");
}
}
function dropdownTips() {
document.getElementById("mydropdown").classList.toggle("show");
}
window.addEventListener("click", function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdowncontent");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
});
//the game
// Declares global variables
let score = 0,
cardToMatch = null;
// Calls `flipCard` on any click
window.addEventListener("click", flipCard);
// Defines the click listener
function flipCard(event) {
// Identifies the card where the click happened
const card = event.target.closest(".card");
// Ignores irrelevant/invalid clicks
if (!card || card.classList.contains("open")) {
return;
}
// A valid click always opens the card
card.classList.add("open");
// If this is the 1st card of 2, remember it
if (cardToMatch === null) {
cardToMatch = card;
} else {
// If it's the 2nd card, compare types
// If they match...
if (card.dataset.type === cardToMatch.dataset.type) {
// ...Increment score and show it in the DOM
updateScoreDisplay(++score);
showPopup();
}
// If they don't...
else {
// ...Flip both cards back over
setTimeout((first, second) => {
first.classList.remove("open");
second.classList.remove("open");
}, 3000, card, cardToMatch);
// Either way, next click will be the 1st of 2
}
cardToMatch = null;
}
}
function updateScoreDisplay(newScore) {
// Syncs the user-displayed value w/ score
const element = document.querySelector(".score span");
element.textContent = newScore;
}
* {
margin: 0;
padding: 0;
font-family: 'Lato', sans-serif;
}
header {
background-color:#00005e;
height: 50px;
position: relative;
}
header h1 {
color: white;
position: absolute;
top: 10%;
left: 38%;
right: 40%;
width: 355px;
}
/*The 'tips?' button and the drop down content*/
header button {
display: inline-flex;
position:absolute;
align-items: center;
right: 2%;
top: 15%;
bottom: 15%;
padding: 10px 20px;
font-size: 20px;
background-color:white;
color: #00005e;
border-radius: 10px;
cursor: pointer;
border-color: transparent;
}
header button:hover {
opacity: 80%;
}
.dropdowncontent {
display: none;
position: absolute;
right: 0%;
top: 100%;
background-color:#010169;
min-width: 160px;
max-width: 400px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.808);
border-bottom-left-radius: 20px;
z-index: 100;
}
.dropdowncontent li {
color: white;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.advise{
font-size: 19px;
}
.passwordtips {
font-size: 30px;
left: 20%;
}
.show {
display:block;
}
/*The link in the dropdowncontent*/
a {
text-decoration: underline;
color: white;
}
a:hover {
cursor: pointer;
}
/*The score counter*/
.score {
color: #01016e;
display: flex;
justify-content: center;
margin: 10px;
font-size: 30px;
}
/*The game section*/
.sectionOne {
max-width: 1100px;
height: 550px;
display: flex;
justify-content: space-around;
margin-top: 10px;
margin-left: auto;
margin-right: auto;
border-radius: 7px;
border-color: #00005e;
border-style: solid;
border-width: 5px;
position: relative;
}
/*The sections content*/
.wrapper {
width: 99%;
height: 100%;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 183px;
margin-top: 7px;
}
.card{
background-color: #01016e;
color: white;
margin: 10px 10px;
height: 150px;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
font-size: 0;
border-radius: 5px;
}
.card h2{
padding: 2px;
transform: scale(-1,1);
}
.card:hover {
cursor: pointer;
}
.open{
animation: flip .5s;
animation-fill-mode: forwards;
transform-style: preserve-3d;
}
#keyframes flip {
from {
background: #00005e;
font-size: 0;
}
to{
background: rgb(20, 73, 185);
font-size:17px;
transform: rotateY( 180deg );
}
}
/* pop up section */
#popup {
position: absolute;
background-color: white;
width: 700px;
height: 500px;
z-index: 100;
right: 50.5vh;
top: 14%;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.808);
border-radius: 8px;
display: none;
}
.congrats {
position: relative;
display: flex;
justify-content: center;
height: 40px;
top: 20%;
color: #00005e;
font-size: 40px;
}
.matches {
position: relative;
height: 40px;
top: 35%;
color: #00005e;
display: flex;
justify-content: center;
font-size: 30px;
}
.playAgain {
position: absolute;
height: 40px;
width: 150px;
top: 65%;
left: 40%;
cursor: pointer;
color: white;
background-color: #00005e;
border-style: none;
font-size: 20px;
border-radius: 5px;
}
/*The 'DID YOU KNOW' over the ticker*/
.facts {
display: flex;
justify-content: space-around;
margin-top: 15px;
font-size: 20px;
color: #00005e;
}
/*The facts ticker*/
.tcontainer {
max-width: 1100px;
margin-top: 20px;
overflow: hidden;
margin-left: auto;
margin-right: auto;
border-radius: 5px;
z-index: 1000;
}
.ticker-wrap {
width: 100%;
padding-left: 100%;
background-color: #00005e;
}
#keyframes ticker {
0% { transform: translate3d(0, 0, 0); }
100% { transform: translate3d(-100%, 0, 0); }
}
.ticker-move {
display: inline-block;
white-space: nowrap;
padding-right: 100%;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-name: ticker;
animation-duration: 55s;
}
.ticker-move:hover{
animation-play-state: paused;
}
.ticker-item{
display: inline-block;
padding-top: 5px;
padding-bottom: 2px;
padding-right: 3em;
color: white;
min-height: 40px;
font-size: 25px;
}
/*The pause button for the ticker*/
.pause {
display: flex;
justify-content: center;
margin-top: 10px;
}
.pausebutton {
padding: 5px;
border-radius: 3px;
background-color: #00005e;
color: white;
border-style: none;
cursor: pointer;
}
.pausebutton:hover {
background-color: #3c3b6e;
}
<!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">
<link rel="stylesheet" href="css/style.css">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Lato:wght#700&display=swap" rel="stylesheet">
<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon" />
<title>ok</title>
</head>
<body>
<header>
<h1>THE PASSWORD GAME</h1>
<div class="dropdown">
<button onclick="dropdownTips()" class="dropbtn">TIPS?</button>
<div class="dropdowncontent" id="mydropdown" >
<ul>
<li class="passwordtips">Tips for making strong passwords: </li>
<li class="advise">1. Use 16 characters or more (use both uppercase and lowercase letters, number and symbols.)</li>
<li class="advise">2. Never use the same password twice.</li>
<li class="advise">3. Use a password manager.</li>
<li class="advise">4. Don't write your passwords down on paper.</li>
<li class="advise">5. Don't share your passwords with others.</li>
<li class="advise">6. Change your password after a breach.</li>
<li class="advise">7. Sign up for data breach notifications. (like haveibeenpwned.com).</li>
<li class="advise">8. Check your accounts regularly for any suspicious activity. </li>
</ul>
</div>
</div>
</header>
<div class="score">Score:<span> 0</span></div>
<section class="sectionOne">
<div class="wrapper" id="card-deck">
<div class="card" data-type="1"><h2>What information should you NEVER use in a password?</h2></div>
<div id="answerSix" class="card" data-type="6"><h2>1 log in</h2></div>
<div id="cardThree" class="card" data-type="3"><h2>When should you ALWAYS change your password?</h2></div>
<div id="anserFive" class="card" data-type="5"><h2>suspicious activity</h2></div>
<div id="cardTwo" class="card" data-type="2"><h2>Who is it okay to tell your password to?</h2></div>
<div id="answerFour" class="card" data-type="4"><h2>16</h2></div>
<div id="answerThree" class="card" data-type="3"><h2>After a data breach</h2></div>
<div id="answerTwo" class="card" data-type="2"><h2>No one</h2></div>
<div id="CardSix" class="card" data-type="6"><h2>For how many log ins is it okay to use the same password?</h2></div>
<div id="cardFour" class="card" data-type="4"><h2>How many characters should you AT LEAST use in a password?</h2></div>
<div class="card" data-card="firstSet" data-type="1"><h2>Name and Birthday</h2></div>
<div id="cardFive" class="card" data-type="5"><h2>What should you regularly look for in your accounts?</h2></div>
</div>
</section>
<section id="popup">
<h3 class="congrats">Congratulations!</h3>
<h3 class="matches">You got 6/6 matches</h3>
<button class="playAgain">Play again?</button>
</section>
<div class="facts">
<h2>DID YOU KNOW?</h2>
</div>
<div class="tcontainer"><div class="ticker-wrap"><div class="ticker-move">
<div class="ticker-item">There is a hacker attack every 39 seconds.</div>
<div class="ticker-item">90% of passwords can be cracked in less than 6 hours.</div>
<div class="ticker-item">80% of hacking related breaches are linked to insufficient passwords.</div>
<div class="ticker-item">59% use their name or birthday in their password.</div>
<div class="ticker-item">6.850.000 passwords are getting hacked each day.</div>
</div></div></div>
<div class="pause">
<p>Hold your mouse over to pause</p>
</div>
</body>
</html>
And i changed the popup section to id instead of class like this
<section id="popup">
This should work:
//Function for the dropdown content
function dropdownTips() {
document.getElementById("mydropdown").classList.toggle("show");
}
window.addEventListener("click", function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdowncontent");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
});
//the game
// Declares global variables
let score = 0,
cardToMatch = null;
// Calls `flipCard` on any click
window.addEventListener("click", flipCard);
// Defines the click listener
function flipCard(event) {
// Identifies the card where the click happened
const card = event.target.closest(".card");
// Ignores irrelevant/invalid clicks
if (!card || card.classList.contains("open")) {
return;
}
// A valid click always opens the card
card.classList.add("open");
// If this is the 1st card of 2, remember it
if (cardToMatch === null) {
cardToMatch = card;
} else {
// If it's the 2nd card, compare types
// If they match...
if (card.dataset.type === cardToMatch.dataset.type) {
// ...Increment score and show it in the DOM
updateScoreDisplay(++score);
}
// If they don't...
else {
// ...Flip both cards back over
setTimeout((first, second) => {
first.classList.remove("open");
second.classList.remove("open");
}, 3000, card, cardToMatch);
// Either way, next click will be the 1st of 2
}
cardToMatch = null;
}
}
function updateScoreDisplay(newScore) {
// Syncs the user-displayed value w/ score
const element = document.querySelector(".score span");
element.textContent = newScore;
}
// popup section
setInterval(function() {if (score==6) {document.getElementById("popup").style.display = "block";}},1000);
* {
margin: 0;
padding: 0;
font-family: 'Lato', sans-serif;
}
header {
background-color:#00005e;
height: 50px;
position: relative;
}
header h1 {
color: white;
position: absolute;
top: 10%;
left: 38%;
right: 40%;
width: 355px;
}
/*The 'tips?' button and the drop down content*/
header button {
display: inline-flex;
position:absolute;
align-items: center;
right: 2%;
top: 15%;
bottom: 15%;
padding: 10px 20px;
font-size: 20px;
background-color:white;
color: #00005e;
border-radius: 10px;
cursor: pointer;
border-color: transparent;
}
header button:hover {
opacity: 80%;
}
.dropdowncontent {
display: none;
position: absolute;
right: 0%;
top: 100%;
background-color:#010169;
min-width: 160px;
max-width: 400px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.808);
border-bottom-left-radius: 20px;
z-index: 100;
}
.dropdowncontent li {
color: white;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.advise{
font-size: 19px;
}
.passwordtips {
font-size: 30px;
left: 20%;
}
.show {
display:block;
}
/*The link in the dropdowncontent*/
a {
text-decoration: underline;
color: white;
}
a:hover {
cursor: pointer;
}
/*The score counter*/
.score {
color: #01016e;
display: flex;
justify-content: center;
margin: 10px;
font-size: 30px;
}
/*The game section*/
.sectionOne {
max-width: 1100px;
height: 550px;
display: flex;
justify-content: space-around;
margin-top: 10px;
margin-left: auto;
margin-right: auto;
border-radius: 7px;
border-color: #00005e;
border-style: solid;
border-width: 5px;
position: relative;
}
/*The sections content*/
.wrapper {
width: 99%;
height: 100%;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 183px;
margin-top: 7px;
}
.card{
background-color: #01016e;
color: white;
margin: 10px 10px;
height: 150px;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
font-size: 0;
border-radius: 5px;
}
.card h2{
padding: 2px;
transform: scale(-1,1);
}
.card:hover {
cursor: pointer;
}
.open{
animation: flip .5s;
animation-fill-mode: forwards;
transform-style: preserve-3d;
}
#keyframes flip {
from {
background: #00005e;
font-size: 0;
}
to{
background: rgb(20, 73, 185);
font-size:17px;
transform: rotateY( 180deg );
}
}
/* pop up section */
.popup {
position: absolute;
background-color: white;
width: 700px;
height: 500px;
z-index: 100;
right: 50.5vh;
top: 14%;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.808);
border-radius: 8px;
display: none;
}
.congrats {
position: relative;
display: flex;
justify-content: center;
height: 40px;
top: 20%;
color: #00005e;
font-size: 40px;
}
.matches {
position: relative;
height: 40px;
top: 35%;
color: #00005e;
display: flex;
justify-content: center;
font-size: 30px;
}
.playAgain {
position: absolute;
height: 40px;
width: 150px;
top: 65%;
left: 40%;
cursor: pointer;
color: white;
background-color: #00005e;
border-style: none;
font-size: 20px;
border-radius: 5px;
}
/*The 'DID YOU KNOW' over the ticker*/
.facts {
display: flex;
justify-content: space-around;
margin-top: 15px;
font-size: 20px;
color: #00005e;
}
/*The facts ticker*/
.tcontainer {
max-width: 1100px;
margin-top: 20px;
overflow: hidden;
margin-left: auto;
margin-right: auto;
border-radius: 5px;
z-index: 1000;
}
.ticker-wrap {
width: 100%;
padding-left: 100%;
background-color: #00005e;
}
#keyframes ticker {
0% { transform: translate3d(0, 0, 0); }
100% { transform: translate3d(-100%, 0, 0); }
}
.ticker-move {
display: inline-block;
white-space: nowrap;
padding-right: 100%;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-name: ticker;
animation-duration: 55s;
}
.ticker-move:hover{
animation-play-state: paused;
}
.ticker-item{
display: inline-block;
padding-top: 5px;
padding-bottom: 2px;
padding-right: 3em;
color: white;
min-height: 40px;
font-size: 25px;
}
/*The pause button for the ticker*/
.pause {
display: flex;
justify-content: center;
margin-top: 10px;
}
.pausebutton {
padding: 5px;
border-radius: 3px;
background-color: #00005e;
color: white;
border-style: none;
cursor: pointer;
}
.pausebutton:hover {
background-color: #3c3b6e;
}
<!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">
<link rel="stylesheet" href="css/style.css">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Lato:wght#700&display=swap" rel="stylesheet">
<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon" />
<title>The Password Game</title>
</head>
<body>
<header>
<h1>THE PASSWORD GAME</h1>
<div class="dropdown">
<button onclick="dropdownTips()" class="dropbtn">TIPS?</button>
<div class="dropdowncontent" id="mydropdown" >
<ul>
<li class="passwordtips">Tips for making strong passwords: </li>
<li class="advise">1. Use 16 characters or more (use both uppercase and lowercase letters, number and symbols.)</li>
<li class="advise">2. Never use the same password twice.</li>
<li class="advise">3. Use a password manager.</li>
<li class="advise">4. Don't write your passwords down on paper.</li>
<li class="advise">5. Don't share your passwords with others.</li>
<li class="advise">6. Change your password after a breach.</li>
<li class="advise">7. Sign up for data breach notifications. (like haveibeenpwned.com).</li>
<li class="advise">8. Check your accounts regularly for any suspicious activity. </li>
</ul>
</div>
</div>
</header>
<div class="score">Score:<span> 0</span></div>
<section class="sectionOne">
<div class="wrapper" id="card-deck">
<div class="card" data-type="1"><h2>What information should you NEVER use in a password?</h2></div>
<div id="answerSix" class="card" data-type="6"><h2>1 log in</h2></div>
<div id="cardThree" class="card" data-type="3"><h2>When should you ALWAYS change your password?</h2></div>
<div id="anserFive" class="card" data-type="5"><h2>suspicious activity</h2></div>
<div id="cardTwo" class="card" data-type="2"><h2>Who is it okay to tell your password to?</h2></div>
<div id="answerFour" class="card" data-type="4"><h2>16</h2></div>
<div id="answerThree" class="card" data-type="3"><h2>After a data breach</h2></div>
<div id="answerTwo" class="card" data-type="2"><h2>No one</h2></div>
<div id="CardSix" class="card" data-type="6"><h2>For how many log ins is it okay to use the same password?</h2></div>
<div id="cardFour" class="card" data-type="4"><h2>How many characters should you AT LEAST use in a password?</h2></div>
<div class="card" data-card="firstSet" data-type="1"><h2>Name and Birthday</h2></div>
<div id="cardFive" class="card" data-type="5"><h2>What should you regularly look for in your accounts?</h2></div>
</div>
</section>
<section class="popup" id="popup">
<h3 class="congrats">Congratulations!</h3>
<h3 class="matches">You got 6/6 matches</h3>
<button class="playAgain">Play again?</button>
</section>
<div class="facts">
<h2>DID YOU KNOW?</h2>
</div>
<div class="tcontainer"><div class="ticker-wrap"><div class="ticker-move">
<div class="ticker-item">There is a hacker attack every 39 seconds.</div>
<div class="ticker-item">90% of passwords can be cracked in less than 6 hours.</div>
<div class="ticker-item">80% of hacking related breaches are linked to insufficient passwords.</div>
<div class="ticker-item">59% use their name or birthday in their password.</div>
<div class="ticker-item">6.850.000 passwords are getting hacked each day.</div>
</div></div></div>
<div class="pause">
<p>Hold your mouse over to pause</p>
</div>
<script src="javascript/javascript.js" ></script>
</body>
</html>
The reason why your code wasn't working was because the code you had only checked if the score was 6 at the start of the game. I fixed this by using the function setInterval which checked if the user had finished the game every second.
More Explanations
If you would like to learn more about the setInterval function, visit:
https://www.w3schools.com/jsref/met_win_setinterval.asp
i just learned how to create a to-do list in java script and as a personal project i wanted to use the information i learned in to-do app making by creating a tell your secret website which like the
const mytext = document.getElementById('mytext');
const btn = document.getElementById('btn');
const items = document.getElementById('items');
btn.addEventListener('click', function(e){
e.preventDefault();
const paragraph = document.createElement('p');
paragraph.classList.add("item");
paragraph.innerText = mytext.value;
items.appendChild(paragraph);
mytext.value = '';
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: rgb(231, 237, 241);
}
main {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 10%;
font-family: "Source Sans Pro", sans-serif;
}
h2 {
color: rgb(71, 80, 102);
font-size: 40px;
margin-bottom: 30px;
}
.myform {
display: flex;
justify-content: center;
align-items: center;
}
#btn {
margin-left: 10px;
width: 40px;
height: 100px;
white-space: pre-line;
text-align: center;
font-size: 15px;
font-weight: 600;
border: none;
border-radius: 10px;
cursor: pointer;
box-shadow: 2px 2px rgb(184, 182, 182);
color: rgb(35, 70, 136);
}
#btn:active {
color: rgb(48, 95, 182);
box-shadow: 0 0 2px grey;
}
#mytext {
background-color: aliceblue;
border-radius: 10px;
border: none;
padding: 7px;
box-shadow: 1px 1px rgb(200, 207, 212);
outline: none;
}
.items {
border-radius: 5px;
font-family: cursive;
color: rgb(61, 61, 60);
width: 400px;
display: flex;
justify-content: center;
margin-top: 10px;
padding: 5px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=MedievalSharp&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght#200;300;400;600;700;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="./styles.css">
<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>
<main>
<h2>Write Your Secret</h2>
<div class="container">
<form class="myform" action="">
<textarea name="text" id="mytext" cols="30" rows="10" placeholder="Write Whatever You Wish"></textarea>
<button id="btn">S
h
a
r
e</button>
</form>
<div class="items" id="items"></div>
</div>
</main>
<script src="./app.js"></script>
</body>
</html>
to-do app user writes something in the box (his/her secret) and the secret is displayed on the screen but
this is what i need:
i need the displayed paragraph to be removed automatically after 2 second like the secret vanishes 2 second after you write it.even better if it vanishes slowly like the ink vanishes in harry potter movie in tom riddle diary but that's not important i just want to remove the secret after 2 seconds first and then worry about the style that it vanishes.
With the simple addition of this code:
setTimeout(() => paragraph.classList.add("hidden"), 2000)
Which adds the class "hidden" after 2 seconds it will do what you want. You could make class hidden do anything, such as just set the visibility to hidden but you can also do transition effects like the one you deswcribe:
.hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
If using a transition like above you can also add this line to remove the element when the transition completes
paragraph.addEventListener('transitionend',() => paragraph.remove())
Live example below
const mytext = document.getElementById('mytext');
const btn = document.getElementById('btn');
const items = document.getElementById('items');
btn.addEventListener('click', function(e){
e.preventDefault();
const paragraph = document.createElement('p');
paragraph.classList.add("item");
paragraph.innerText = mytext.value;
items.appendChild(paragraph);
mytext.value = '';
paragraph.addEventListener('transitionend',() => paragraph.remove())
setTimeout(() => paragraph.classList.add("hidden"), 2000)
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: rgb(231, 237, 241);
}
main {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 10%;
font-family: "Source Sans Pro", sans-serif;
}
h2 {
color: rgb(71, 80, 102);
font-size: 40px;
margin-bottom: 30px;
}
.myform {
display: flex;
justify-content: center;
align-items: center;
}
#btn {
margin-left: 10px;
width: 40px;
height: 100px;
white-space: pre-line;
text-align: center;
font-size: 15px;
font-weight: 600;
border: none;
border-radius: 10px;
cursor: pointer;
box-shadow: 2px 2px rgb(184, 182, 182);
color: rgb(35, 70, 136);
}
#btn:active {
color: rgb(48, 95, 182);
box-shadow: 0 0 2px grey;
}
#mytext {
background-color: aliceblue;
border-radius: 10px;
border: none;
padding: 7px;
box-shadow: 1px 1px rgb(200, 207, 212);
outline: none;
}
.items {
border-radius: 5px;
font-family: cursive;
color: rgb(61, 61, 60);
width: 400px;
display: flex;
justify-content: center;
margin-top: 10px;
padding: 5px;
}
.hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
<main>
<h2>Write Your Secret</h2>
<div class="container">
<form class="myform" action="">
<textarea name="text" id="mytext" cols="30" rows="10" placeholder="Write Whatever You Wish"></textarea>
<button id="btn">S
h
a
r
e</button>
</form>
<div class="items" id="items"></div>
</div>
</main>
const btn = document.getElementById('btn');
const items = document.getElementById('items');
const clearInput = () => {
setInterval(function(){mytext.value = ''; }, 2000);
}
btn.addEventListener('click', function(e){
e.preventDefault();
const paragraph = document.createElement('p');
paragraph.classList.add("item");
paragraph.innerText = mytext.value;
items.appendChild(paragraph);
mytext.value = '';
});
clearInput()