The changing volume icon pushes the volume slider. css problem - javascript

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

Related

app.js:12 Uncaught TypeError: Cannot read properties of undefined (reading 'className') at HTMLDivElement.<anonymous> (app.js:12:53)

I have ran into a problem. I have a website and some buttons to the right.
using JS, I want to change the style of the button we click on.
When you land on the page, the home button will have a background-color: green. But when you click another button, the home button background-color becomes black/gray. But the background-color of button you clicked will stay black/gray and no error will appear in the console. But when you click any other button after clicking the first time, the background-color will stay gray/black but an error appears in the console :
app.js:12 Uncaught TypeError: Cannot read properties of undefined (reading 'className') at HTMLDivElement.<anonymous> (app.js:12:53)
The code :
const sections = document.querySelectorAll('.section');
const sectBtns = document.querySelectorAll('.controls');
const sectBtn = document.querySelectorAll('.control');
const allSection = document.querySelector('.main-content');
function PageTransitions() {
// Button click active class
for (let i = 0; i < sectBtn.length; i++) {
sectBtn[i].addEventListener('click', function() {
let currentBtn = document.querySelectorAll('.active-btn');
currentBtn[0].className = currentBtn[0].className.replace('active-btn', '');
this.className += 'active-btn';
})
}
}
PageTransitions();
* {
margin: 0;
padding: 0;
box-sizing: border-box;
list-style: none;
}
:root {
--color-primary: #191d2b;
--color-secondary: #27AE60;
--color-white: #FFFFFF;
--color-black: #000;
--color-grey0: #f8f8f8;
--color-grey-1: #dbe1e8;
--color-grey-2: #b2becd;
--color-grey-3: #6c7983;
--color-grey-4: #454e56;
--color-grey-5: #2a2e35;
--color-grey-6: #12181b;
--br-sm-2: 14px;
--box-shadow-1: 0 3px 15px rgba(0, 0, 0, .3);
}
body {
background-color: var(--color-primary);
font-family: "Poppins", sans-serif;
font-size: 1.1rem;
color: var(--color-white);
transition: all 0.4s ease-in-out;
}
a {
display: inline-block;
color: inherit;
font-family: inherit;
text-decoration: none;
}
header {
height: 100vh;
color: var(--color-white);
overflow: hidden;
}
section {
min-height: 100vh;
width: 100%;
position: absolute;
top: 0;
left: 0;
padding: 3rem 18rem;
}
.section {
transform: translateY(-100%) scale(0);
transition: all 0.4s ease-in-out;
background-color: var(--color-primary);
}
.sec1 {
display: none;
transform: translateY(0) scale(1);
}
.sec2 {
display: none;
transform: translateY(0) scale(1);
}
.sec3 {
display: none;
transform: translateY(0) scale(1);
}
.sec4 {
display: none;
transform: translateY(0) scale(1);
}
.sec5 {
display: none;
transform: translateY(0) scale(1);
}
.controls {
position: fixed;
z-index: 10;
top: 50%;
right: 3%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
transform: translateY(-50%);
}
.controls .active-btn {
background-color: var(--color-secondary) !important;
transition: all 0.4s ease-in-out;
}
.controls .active-btn i {
color: var(--color-white) !important;
}
.controls .control {
padding: 1rem;
cursor: pointer;
background-color: var(--color-grey-4);
width: 55px;
height: 55px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0.7rem 0;
box-shadow: var(--box-shadow-1);
}
.controls .control i {
font-size: 1.2rem;
color: var(--color-grey-2);
pointer-events: none;
}/*# sourceMappingURL=style.css.map */
<!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>Portfolio</title>
<link rel="stylesheet" href="file://C:\Users\emile\Desktop\Portfolio Website\styles\style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght#400;500;600;700;800&display=swap" rel="stylesheet">
</head>
<body class="main-content">
<header class="section sec1 header active"></header>
<main>
<section class="section sec2 about"></section>
<section class="section sec3 portfolio"></section>
<section class="section sec4 blogs"></section>
<section class="section sec5 contact"></section>
</main>
<div class="controls">
<div class="control control-1 active-btn" data-id="header">
<i class="fas fa-home"></i>
</div>
<div class="control control-2" data-id="about">
<i class="fas fa-user"></i>
</div>
<div class="control control-3" data-id="portfolio">
<i class="fas fa-briefcase"></i>
</div>
<div class="control control-4" data-id="blogs">
<i class="fas fa-newspaper"></i>
</div>
<div class="control control-5" data-id="contact">
<i class="fas fa-envelope-open"></i>
</div>
</div>
<script src="C:\Users\emile\Desktop\Portfolio Website\app.js"></script>
</body>
</html>
Due to this the background color does not change.
Any idea on how to fix that ?
Thanks !
You have done everything right but you have to give space while giving the class name.
In your js code
in place of this.className += 'active-btn';
You have to write this.className += ' active-btn';
Just a space "__"
Now you can see things are working well!
const sections = document.querySelectorAll('.section');
const sectBtns = document.querySelectorAll('.controls');
const sectBtn = document.querySelectorAll('.control');
const allSection = document.querySelector('.main-content');
function PageTransitions() {
// Button click active class
for (let i = 0; i < sectBtn.length; i++) {
sectBtn[i].addEventListener('click', function() {
let currentBtn = document.querySelectorAll('.active-btn');
currentBtn[0].className = currentBtn[0].className.replace('active-btn', '');
this.className += ' active-btn';
})
}
}
PageTransitions();
* {
margin: 0;
padding: 0;
box-sizing: border-box;
list-style: none;
}
:root {
--color-primary: #191d2b;
--color-secondary: #27AE60;
--color-white: #FFFFFF;
--color-black: #000;
--color-grey0: #f8f8f8;
--color-grey-1: #dbe1e8;
--color-grey-2: #b2becd;
--color-grey-3: #6c7983;
--color-grey-4: #454e56;
--color-grey-5: #2a2e35;
--color-grey-6: #12181b;
--br-sm-2: 14px;
--box-shadow-1: 0 3px 15px rgba(0, 0, 0, .3);
}
body {
background-color: var(--color-primary);
font-family: "Poppins", sans-serif;
font-size: 1.1rem;
color: var(--color-white);
transition: all 0.4s ease-in-out;
}
a {
display: inline-block;
color: inherit;
font-family: inherit;
text-decoration: none;
}
header {
height: 100vh;
color: var(--color-white);
overflow: hidden;
}
section {
min-height: 100vh;
width: 100%;
position: absolute;
top: 0;
left: 0;
padding: 3rem 18rem;
}
.section {
transform: translateY(-100%) scale(0);
transition: all 0.4s ease-in-out;
background-color: var(--color-primary);
}
.sec1 {
display: none;
transform: translateY(0) scale(1);
}
.sec2 {
display: none;
transform: translateY(0) scale(1);
}
.sec3 {
display: none;
transform: translateY(0) scale(1);
}
.sec4 {
display: none;
transform: translateY(0) scale(1);
}
.sec5 {
display: none;
transform: translateY(0) scale(1);
}
.controls {
position: fixed;
z-index: 10;
top: 50%;
right: 3%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
transform: translateY(-50%);
}
.controls .active-btn {
background-color: var(--color-secondary) !important;
transition: all 0.4s ease-in-out;
}
.controls .active-btn i {
color: var(--color-white) !important;
}
.controls .control {
padding: 1rem;
cursor: pointer;
background-color: var(--color-grey-4);
width: 55px;
height: 55px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0.7rem 0;
box-shadow: var(--box-shadow-1);
}
.controls .control i {
font-size: 1.2rem;
color: var(--color-grey-2);
pointer-events: none;
}/*# sourceMappingURL=style.css.map */
<!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>Portfolio</title>
<link rel="stylesheet" href="file://C:\Users\emile\Desktop\Portfolio Website\styles\style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght#400;500;600;700;800&display=swap" rel="stylesheet">
</head>
<body class="main-content">
<header class="section sec1 header active"></header>
<main>
<section class="section sec2 about"></section>
<section class="section sec3 portfolio"></section>
<section class="section sec4 blogs"></section>
<section class="section sec5 contact"></section>
</main>
<div class="controls">
<div class="control control-1 active-btn" data-id="header">
<i class="fas fa-home"></i>
</div>
<div class="control control-2" data-id="about">
<i class="fas fa-user"></i>
</div>
<div class="control control-3" data-id="portfolio">
<i class="fas fa-briefcase"></i>
</div>
<div class="control control-4" data-id="blogs">
<i class="fas fa-newspaper"></i>
</div>
<div class="control control-5" data-id="contact">
<i class="fas fa-envelope-open"></i>
</div>
</div>
<script src="C:\Users\emile\Desktop\Portfolio Website\app.js"></script>
</body>
</html>
you need to change this line
this.className += 'active-btn';
to
sectBtn[i].classList.add("active-btn")
reason, this keyword will point current class object or functionality but in your case you need to take btn whichever you're clicking and add class to that button. So, we use classList for add new class in html element.

having errors while trying to switch between sections on portfolio website

I'm trying to make a javascript function that will allow me to toggle between sections of my portfolio website, but the code starts crashing after a while.
It works for a moment and then gives me error saying "app.js:10 Uncaught TypeError: Cannot read properties of undefined (reading 'className') at HTMLDivElement. (app.js:10:53)".
enter image description here (here is the pic of the problem)
Does anyone know how to solve this issue?
Here goes the code:
const sections = document.querySelectorAll('.section');
const sectBtns = document.querySelectorAll(".controlls");
const sectBtn = document.querySelectorAll(".control");
const allSections = document.querySelector('.main-content');
function PageTransitions() {
for (let i = 0; i < sectBtn.length; i++) {
sectBtn[i]. addEventListener("click", function() {
let currentBtn = document.querySelectorAll('.active-btn');
currentBtn[0].className = currentBtn[0].className.replace('active-btn','');
this.className += 'active-btn';
})
}
allSections.addEventListener('click', (e)=> {
const id = e.target.dataset.id;
if (id) {
sectBtns.forEach((btn) => {
btn.classList.remove('active')
})
e.target.classList.add('active')
sections.forEach((section)=> {
section.classList.remove('active')
})
const element = document.getElementById(id);
element.classList.add('active');
}
})
}
PageTransitions();
<!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>Portfolio</title>
<link rel="stylesheet" href="styles/styles.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
<script src="https://kit.fontawesome.com/25c3cf235c.js" crossorigin="anonymous"></script>
</head>
<body class="main-content">
<header class="section sec1 header active" id ="home">
</header>
<main>
<section class="section sec2 about" id ="about"></section>
<section class="section sec3 portfolio" id ="portfolio"></section>
<section class="section sec4 blogs" id ="blogs"></section>
<section class="section sec5 contact" id ="contact"></section>
</main>
<div class="controlls">
<div class="control control-1 active-btn" data-id ="home">
<i class="fa-solid fa-house-user"></i>
</div>
<div class="control control-2 " data-id ="about">
<i class="fa-solid fa-user"></i>
</div>
<div class="control control-3 " data-id ="portfolio">
<i class="fa-solid fa-briefcase"></i>
</div>
<div class="control control-4 " data-id ="blogs">
<i class="fa-solid fa-newspaper"></i>
</div>
<div class="control control-5 " data-id ="contact">
<i class="fa-solid fa-envelope"></i>
</div>
</div>
<script src = "app.js"></script>
</body>
</html>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
list-style: none;
}
:root {
--color-primary: #191d2b;
--color-secondary: #27AE60;
--color-white: #FFFFFF;
--color-black: #000;
--color-grey0: #f8f8f8;
--color-grey-1: #dbe1e8;
--color-grey-2: #b2becd;
--color-grey-3: #6c7983;
--color-grey-4: #454e56;
--color-grey-5: #2a2e35;
--color-grey-6: #12181b;
--br-sm-2: 14px;
--box-shadow-1: 0 3px 15px rgba(0,0,0,.3);
}
body {
font-family: 'Poppins', sans-serif;
background-color: var(--color-primary);
font-size: 1.1rem;
color: var(--color-white );
transition: all .4s ease-in-out;
}
a {
display: inline-block;
text-decoration: none;
color: inherit;
font-family: inherit;
}
header {
height: 100vh;
color: var(--color-white);
overflow: hidden;
}
section {
min-height: 100vh;
width: 100%;
position: absolute;
left: 0;
top: 0;
padding: 3rem 18rem;
}
.section {
transform: translateY(-100%) scale(0);
transition: all .4 ease-in-out;
background-color: var(--color-primary);
}
.sec1 {
display: none;
transform: translateV(0) scale(1);
background-color: rgb(26, 22, 50);
}
.sec2 {
display: none;
transform: translateV(0) scale(1);
background-color: slateblue;
}
.sec3 {
display: none;
transform: translateV(0) scale(1);
background-color: rgb(127, 123, 151);
}
.sec4 {
display: none;
transform: translateV(0) scale(1);
}
.sec5 {
display: none;
transform: translateV(0) scale(1);
}
.controlls {
position: fixed;
z-index: 10;
top: 50%;
right: 3%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
transform: translateY(-50%);
.active-btn {
background-color: var(--color-secondary) !important;
transition: all .4s ease-in-out;
i {
color: var(--color-white) !important;
}
}
.control {
padding: 1rem;
cursor: pointer;
background-color: var(--color-grey-4);
width: 55px;
height: 55px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
margin: .7rem 0;
box-shadow: var(--box-shadow-1);
i {
font-size: 1.2rem;
color: var(--color-grey-2);
pointer-events: none;
}
}
}
currentBtn[0].className = currentBtn[0].className.replace('active-btn',''); //error because className is for react development . and basically here you only want to remove a class from the element and add another element.
currentBtn[0].classList.remove("active-btn")
currentBtn[0].classList.add("your new class" write here);

my popup should show when score = 6, but i cant make it work

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

Mouseover event with mousedown

I need your help. There is an APP Virtual-piano. When I click the key, the relevent note is reproduced.If the click is single, everything is fine. But when I hold down the mouse button and lead the cursor over the keys, the sound is not produced. What could be the problem? I suppose that the problem is in function on the line 15. But i don`t know how to fix it. Help me please. Thanks in advance.
This is JS code
const piano = document.querySelector(".piano");
const collectionPiano = document.querySelectorAll(".piano-key");
function setActiveKey(event) { //active status keys mouse event
event.target.classList.add("piano-key-active", "piano-key-active-pseudo");
}
function removeActiveKey(event) { //remove active status keys mouse event
event.target.classList.remove("piano-key-active", "piano-key-active-pseudo");
}
function playAudio (note) { //start function playAudio
const audio = document.querySelector(`audio[data-note="${note}"]`);
audio.currentTime = 0;
audio.play();
}
function startKeyActive (event) { //mouseover and mouseout events for active status keys, pseudo and play audio
if (event.target.classList.contains("piano-key")) {
event.target.classList.add("piano-key-active", "piano-key-active-pseudo");
const note = event.target.dataset.note;
playAudio(note);
}
collectionPiano.forEach((el) => {
// el.addEventListener("mouseover", playAudio);
el.addEventListener("mouseover", setActiveKey);
el.addEventListener("mouseout", removeActiveKey);
});
};
function stopKeyIActive () { //remove mouseover and mouseout events for active status keys, pseudo and play audio
collectionPiano.forEach((el) => {
el.classList.remove("piano-key-active", "piano-key-active-pseudo");
// el.removeEventListener("mouseover", playAudio);
el.removeEventListener("mouseover", setActiveKey);
el.removeEventListener("mouseout", removeActiveKey);
});
};
piano.addEventListener("mousedown", startKeyActive);
piano.addEventListener("mousedown", playAudio);
document.addEventListener("mouseup", stopKeyIActive);
window.addEventListener("keydown", (event) => { // Event keyboard - play audio
if (event.repeat) {
return;
}
const audioKeys = document.querySelector(`audio[data-key="${event.keyCode}"]`);
const pianoKey = document.querySelector(`.piano-key[data-key="${event.keyCode}"]`);
audioKeys.currentTime = 0;
audioKeys.play();
pianoKey.classList.add('piano-key-active');
window.addEventListener("keyup", () => {
pianoKey.classList.remove('piano-key-active');
})
});
* {
padding: 0;
margin: 0;
box-sizing: border-box;
user-select: none;
}
a:focus {
outline: 0;
}
html {
background: #313940;
}
body {
min-height: 100vh;
background-color: #313940;
font-family: "Open Sans", Arial, Helvetica, sans-serif;
background: #313940;
overflow-x: hidden;
}
.header {
text-align: center;
width: 100%;
border-bottom: 1px solid;
border-image-slice: 1;
border-image-source: linear-gradient(to left, #38495a, #a2abb3, #38495a);
}
.header-title {
line-height: 60px;
font-weight: 300;
color: #fff;
}
.main {
min-height: calc(100vh - 110px);
padding: 60px 10px 0;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: space-between;
width: 100%;
max-width: 1140px;
margin: 0 auto;
}
.btn-container {
display: flex;
justify-content: space-between;
width: 306px;
height: 40px;
margin: 0 auto;
margin-bottom: 80px;
}
.btn {
width: 150px;
height: 40px;
padding: 0 10px;
background-color: #454c53;
border: 0;
border-radius: 2px;
font-family: "Open Sans", sans-serif;
font-size: 16px;
font-weight: 300;
color: #fff;
outline: 0;
cursor: pointer;
transition: 0.3s;
}
.btn:not(.btn-active):hover {
background-color: #515961;
}
.btn:active {
background-color: #00c9b7;
}
.btn-active {
background-color: #00b4a4;
}
.btn-active:hover {
background-color: #00c9b7;
}
.piano {
position: relative;
display: flex;
justify-content: space-between;
width: 100%;
height: 270px;
max-width: 560px;
margin: 0 auto 60px;
}
.piano-key {
position: relative;
width: 80px;
height: 270px;
background-color: rgba(255, 255, 255, 0.85);
border: 4px solid #313940;
border-radius: 0px 0px 12px 12px;
transition: 0.3s;
cursor: pointer;
}
.piano-key:hover {
background-color: #fff;
}
.keys-sharp {
position: absolute;
top: 0;
bottom: 0;
left: 53px;
right: 53px;
display: flex;
justify-content: space-between;
pointer-events: none;
}
.piano-key.sharp {
width: 54px;
height: 170px;
background-color: #313940;
border: 0;
border-radius: 0px 0px 9px 9px;
top: 0;
z-index: 3;
pointer-events: auto;
transform-origin: center top;
}
.piano-key.piano-key-active,
.piano-key.sharp.piano-key-active {
transform: scale(0.96);
}
.piano-key.none {
background-color: transparent;
border: 0;
border-radius: 0;
pointer-events: none;
}
.piano-key::before,
.piano-key::after {
content: attr(data-note);
position: absolute;
width: 40px;
height: 40px;
font-size: 26px;
line-height: 40px;
text-align: center;
color: #a2abb3;
bottom: -45px;
left: 20px;
transition: 0.3s;
pointer-events: none;
}
.piano-key::after {
display: none;
content: attr(data-letter);
}
.piano-key:hover::before,
.piano-key:hover::after {
color: #d7dfe6;
}
.sharp:active {
border-top: 0;
}
.piano-key.sharp::before,
.piano-key.sharp::after {
bottom: 175px;
left: 7px;
}
.piano-key.letter::before {
display: none;
}
.piano-key.letter::after {
display: block;
}
.piano-key-letter::before {
content: attr(data-letter);
}
.piano-key-remove-mouse:active::before {
color: #a2abb3;
}
.piano-key-active-pseudo:hover::after,
.piano-key-active-pseudo:hover::before,
.piano-key-active::after,
.piano-key-active::before {
color: #00b4a4;
}
.fullscreen {
position: fixed;
top: 120px;
right: 40px;
width: 40px;
height: 40px;
background-color: rgba(255, 255, 255, 0.3);
border: 0;
outline: 0;
background-size: contain;
transition: 0.3s;
cursor: pointer;
background-image: url("assets/svg/fullscreen-open.svg");
}
.fullscreen:hover {
background-color: rgba(255, 255, 255, 0.5);
}
:-webkit-full-screen .fullscreen {
background-image: url("assets/svg/fullscreen-exit.svg");
}
.footer {
border-top: 1px solid;
border-image-slice: 1;
border-image-source: linear-gradient(to left, #38495a, #a2abb3, #38495a);
}
.footer-container {
padding: 0 15px;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
max-width: 1140px;
margin: 0 auto;
}
.github {
display: block;
width: 120px;
height: 45px;
padding-left: 45px;
background-image: url("assets/svg/github.svg");
background-size: 35px;
background-repeat: no-repeat;
background-position: left center;
line-height: 45px;
color: #cbd5de;
font-size: 16px;
font-family: "Open Sans", sans-serif;
transition: 0.3s;
}
.github:hover {
color: #fff;
}
.rss {
display: block;
position: relative;
font-family: "Open Sans", sans-serif;
width: 86px;
height: 32px;
background-image: url("assets/svg/rss.svg");
background-size: contain;
background-repeat: no-repeat;
background-position: left center;
padding-right: 111px;
}
.rss-year {
position: absolute;
bottom: 0;
right: 0;
font-size: 21px;
letter-spacing: -2px;
color: #cbd5de;
line-height: 0.9;
font-weight: bold;
transition: 0.3s;
}
.rss:hover .rss-year {
right: -5px;
letter-spacing: 0;
}
#media (max-width: 768px) {
.fullscreen {
top: 10px;
right: 20px;
width: 40px;
height: 40px;
}
}
#media (max-width: 600px) {
.main {
padding-top: 40px;
}
.piano {
width: 310px;
height: 160px;
}
.piano-key {
width: 44px;
height: 160px;
border-radius: 0px 0px 8px 8px;
border: 2px solid #313940;
}
.keys-sharp {
left: 26px;
right: 26px;
}
.piano-key.sharp {
width: 36px;
height: 100px;
border-radius: 0px 0px 6px 6px;
}
.piano-key::before,
.piano-key::after {
width: 30px;
height: 30px;
font-size: 22px;
bottom: -35px;
left: 7px;
font-size: 22px;
}
.piano-key.sharp::before,
.piano-key.sharp::after {
bottom: 115px;
left: 3px;
}
.btn-container {
width: 244px;
height: 40px;
margin-bottom: 80px;
}
.btn {
width: 120px;
height: 40px;
}
}
<!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 href="assets/piano.ico" rel="shortcut icon">
<link href="https://fonts.gstatic.com" rel="preconnect">
<link
href="https://fonts.googleapis.com/css2?family=Open+Sans+Condensed:wght#300&family=Open+Sans:wght#300;400;800&display=swap"
rel="stylesheet">
<link href="style.css" rel="stylesheet">
<title>virtual-piano</title>
</head>
<body>
<header class="header">
<h1 class="header-title">Virtual Piano</h1>
</header>
<main class="main">
<div class="btn-container">
<button class="btn btn-notes btn-active">Notes</button>
<button class="btn btn-letters">Letters</button>
</div>
<div class="piano">
<div class="piano-key" data-key="68" data-letter="D" data-note="c"></div>
<div class="piano-key" data-key="70" data-letter="F" data-note="d"></div>
<div class="piano-key" data-key="71" data-letter="G" data-note="e"></div>
<div class="piano-key" data-key="72" data-letter="H" data-note="f"></div>
<div class="piano-key" data-key="74" data-letter="J" data-note="g"></div>
<div class="piano-key" data-key="75" data-letter="K" data-note="a"></div>
<div class="piano-key" data-key="76" data-letter="L" data-note="b"></div>
<div class="keys-sharp">
<div class="piano-key sharp" data-key="82" data-letter="R" data-note="c♯"></div>
<div class="piano-key sharp" data-key="84" data-letter="T" data-note="d♯"></div>
<div class="piano-key sharp none"></div>
<div class="piano-key sharp" data-key="85" data-letter="U" data-note="f♯"></div>
<div class="piano-key sharp" data-key="73" data-letter="I" data-note="g♯"></div>
<div class="piano-key sharp" data-key="79" data-letter="O" data-note="a♯"></div>
</div>
</div>
<audio data-key="75" data-note="a" src="assets/audio/a.mp3"></audio>
<audio data-key="79" data-note="a♯" src="assets/audio/a♯.mp3"></audio>
<audio data-key="76" data-note="b" src="assets/audio/b.mp3"></audio>
<audio data-key="68" data-note="c" src="assets/audio/c.mp3"></audio>
<audio data-key="82" data-note="c♯" src="assets/audio/c♯.mp3"></audio>
<audio data-key="70" data-note="d" src="assets/audio/d.mp3"></audio>
<audio data-key="84" data-note="d♯" src="assets/audio/d♯.mp3"></audio>
<audio data-key="71" data-note="e" src="assets/audio/e.mp3"></audio>
<audio data-key="72" data-note="f" src="assets/audio/f.mp3"></audio>
<audio data-key="85" data-note="f♯" src="assets/audio/f♯.mp3"></audio>
<audio data-key="74" data-note="g" src="assets/audio/g.mp3"></audio>
<audio data-key="73" data-note="g♯" src="assets/audio/g♯.mp3"></audio>
<button class="fullscreen openfullscreen"></button>
</main>
<footer class="footer">
<div class="footer-container">
<a class="github" href="#" target="_blank" rel="noopener noreferrer">github</a>
<a class="rss" href="https://rs.school/js/" target="_blank" rel="noopener noreferrer">
<span class="rss-year">'21</span>
</a>
</div>
</footer>
<script src="script.js"></script>
</body>
</html>
I did it, here is the final code JS
const piano = document.querySelector(".piano");
const collectionPiano = document.querySelectorAll(".piano-key");
function playAudio (event) { //active status keys mouse event
event.target.classList.add("piano-key-active", "piano-key-active-pseudo");
const note = event.target.dataset.note;
const audio = document.querySelector(`audio[data-note="${note}"]`);
audio.currentTime = 0;
audio.play();
}
function removeActiveKey(event) { //remove active status keys mouse event
event.target.classList.remove("piano-key-active", "piano-key-active-pseudo");
}
function startKeyActive (event) { //mouseover and mouseout events for active status keys, pseudo and play audio
if (event.target.classList.contains("piano-key")) {
event.target.classList.add("piano-key-active", "piano-key-active-pseudo");
}
collectionPiano.forEach((el) => {
el.addEventListener("mouseover", playAudio);
el.addEventListener("mouseout", removeActiveKey);
});
};
function stopKeyIActive () { //remove mouseover and mouseout events for active status keys, pseudo and play audio
collectionPiano.forEach((el) => {
el.classList.remove("piano-key-active", "piano-key-active-pseudo");
el.removeEventListener("mouseover", playAudio);
el.removeEventListener("mouseout", removeActiveKey);
});
};
piano.addEventListener("mousedown", startKeyActive);
piano.addEventListener("mousedown", playAudio);
document.addEventListener("mouseup", stopKeyIActive);
window.addEventListener("keydown", (event) => { // Event keyboard - play audio
if (event.repeat) {
return;
}
const audioKeys = document.querySelector(`audio[data-key="${event.keyCode}"]`);
const pianoKey = document.querySelector(`.piano-key[data-key="${event.keyCode}"]`);
audioKeys.currentTime = 0;
audioKeys.play();
pianoKey.classList.add('piano-key-active');
window.addEventListener("keyup", () => {
pianoKey.classList.remove('piano-key-active');
})
});

js for custom select works in codepen and jsfiddle but not in browser?

I'm working on a custom select element, the code runs as expected in codepen and jsfiddle, but won't drop down if I run it in browser. I've never implemented js in a web project before so I feel like I'm missing something fairly simple.
here's the link to the codepen: https://codepen.io/kylegendy/pen/xxwYrPr
and here's the code I put in...:
script.js
for (const dropdown of document.querySelectorAll(".custom-select-wrapper")) {
dropdown.addEventListener('click', function() {
this.querySelector('.custom-select').classList.toggle('open');
})
}
for (const option of document.querySelectorAll(".custom-option")) {
option.addEventListener('click', function() {
if (!this.classList.contains('selected')) {
this.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
this.classList.add('selected');
this.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = this.textContent;
}
})
}
window.addEventListener('click', function(e) {
for (const select of document.querySelectorAll('.custom-select')) {
if (!select.contains(e.target)) {
select.classList.remove('open');
}
}
});
function selectOption(index) {
var optionOnIdx = document.querySelector('.custom-option:nth-child(' + index + ')');
var optionSelected = document.querySelector('.custom-option.selected');
if (optionOnIdx !== optionSelected) {
optionSelected.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
optionOnIdx.classList.add('selected');
optionOnIdx.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = optionOnIdx.textContent;
}
}
document.querySelector('button').addEventListener("click", function() {
selectOption(2);
});
template.css
*,
*:after,
*:before {
box-sizing: border-box;
}
.container .custom-select-wrapper {
display: flex;
text-align: center;
/* centeres the text horizontally */
width: 300px;
border-width: thick;
border-color: blue;
border-style: solid;
}
custom-select-wrapper>div {
display: inline-block;
position: relative;
max-width: 50%;
}
.container .selectName {
display: flex;
justify-content: center;
align-items: center;
position: relative;
user-select: none;
border-width: thick;
border-color: red;
border-style: none solid none none;
background-color: rgba(228, 228, 228, 0.39);
}
.custom-select-wrapper {
position: relative;
user-select: none;
}
.custom-select {
display: flex;
flex-direction: column;
border-width: 0;
}
.custom-select-wrapper>div {
display: inline-block;
/* blocks just line up without floats */
position: relative;
/* sets positioning context for 2nd level menu */
width: 50%;
height: 60px;
}
.custom-select__trigger {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 22px;
color: rgba(83, 83, 83, 1);
line-height: 60px;
background-color: rgba(228, 228, 228, 0.39);
cursor: pointer;
border-width: 0;
}
.custom-options {
position: absolute;
display: block;
top: 100%;
left: 0;
right: 0;
border: none;
background: white;
transition: all 0.5s;
opacity: 0;
visibility: hidden;
}
.custom-select.open .custom-options {
opacity: 1;
visibility: visible;
}
.custom-option {
position: relative;
display: block;
padding: 0 22px 0 22px;
color: rgba(83, 83, 83, 1);
line-height: 60px;
cursor: pointer;
}
.custom-option:hover {
cursor: pointer;
background-color: rgba(228, 228, 228, 0.39);
}
.custom-option.selected {
color: white;
background-color: rgb(149, 189, 204);
}
.arrow {
position: relative;
height: 15px;
width: 15px;
}
.arrow::before,
.arrow::after {
content: "";
position: absolute;
bottom: 0px;
width: 0.15rem;
height: 100%;
transition: all 0.5s;
}
.arrow::before {
left: -5px;
transform: rotate(45deg);
background-color: #394a6d;
}
.arrow::after {
left: 5px;
transform: rotate(-45deg);
background-color: #394a6d;
}
.open .arrow::before {
left: -5px;
transform: rotate(-45deg);
}
.open .arrow::after {
left: 5px;
transform: rotate(45deg);
}
template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>the wall</title>
<link href="template.css" rel="stylesheet" type="text/css">
<script src="script.js" type="text/javascript"></script>
</head>
<body>
<div class="container">
<div class="custom-select-wrapper">
<div class="selectName"><span>Type</span></div>
<div class="custom-select">
<div class="custom-select__trigger"><span>Tesla</span>
<div class="arrow"></div>
</div>
<div class="custom-options">
<span class="custom-option selected" data-value="tesla">Tesla</span>
<span class="custom-option" data-value="volvo">Volvo</span>
<span class="custom-option" data-value="mercedes">Mercedes</span>
</div>
</div>
</div>
</div>
</body>
</html>
edit: I deleted the segment of js code starting at line 38 in jsfiddle and codepen and the dropdown worked the same, the way it’s supposed to, but when I got rid of it in the files to run on browser, although the error disappears, the dropdown still doesn’t work.
Put your script in a function like below
function Test(){
for (const dropdown of document.querySelectorAll(".custom-select-wrapper")) {
dropdown.addEventListener('click', function () {
this.querySelector('.custom-select').classList.toggle('open');
})
}
for (const option of document.querySelectorAll(".custom-option")) {
option.addEventListener('click', function () {
if (!this.classList.contains('selected')) {
this.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
this.classList.add('selected');
this.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = this.textContent;
}
})
}
window.addEventListener('click', function (e) {
for (const select of document.querySelectorAll('.custom-select')) {
if (!select.contains(e.target)) {
select.classList.remove('open');
}
}
});
function selectOption(index) {
var optionOnIdx = document.querySelector('.custom-option:nth-child('+index+')');
var optionSelected = document.querySelector('.custom-option.selected');
if (optionOnIdx !== optionSelected) {
optionSelected.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
optionOnIdx.classList.add('selected');
optionOnIdx.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = optionOnIdx.textContent;
}
}
}
and call this function from your HTML page
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>the wall</title>
<link href="template.css" rel="stylesheet" type="text/css">
<script src="script.js" type="text/javascript"></script>
</head>
<body>
<div class="container">
<div class="custom-select-wrapper">
<div class="selectName"><span>Type</span></div>
<div class="custom-select">
<div class="custom-select__trigger"><span>Tesla</span>
<div class="arrow"></div>
</div>
<div class="custom-options">
<span class="custom-option selected" data-value="tesla">Tesla</span>
<span class="custom-option" data-value="volvo">Volvo</span>
<span class="custom-option" data-value="mercedes">Mercedes</span>
</div>
</div>
</div>
</div>
<script>
Test();
</script>
</body>
</html>
and remove the following piece of code from your script.js page
document.querySelector('button').addEventListener("click", function() {
selectOption(2);
});

Categories

Resources