FullPage.js navigation - javascript

I wanted to make a website using fullpage.js and i did a lot of it but i have a few problems with the navigation. I have used autoscroll which undoubtedly makes things a LOT worse since its my first time using fullpage.js. I had have made a navbar at the top, and Which has a few buttons for the navigation. I wanted to scroll to a section of the page if i click it but the regural scrollTo(); and others doesnt work. I also gave navigations: true using fullpage.js. I tried checking what happens when it autoscrolls,
and i managed to get the scrolling working for the home section, but if i scrolled from the second page to the first using the button, if i scroll down, then it goes to the third page.
Is there anyone who knows a little about fullpage.js?
Heres the code
var place = [];
var dest = [];
animationsAndOther();
buttons();
function animationsAndOther() {
const tl = gsap.timeline({ defaults: { ease: "power1.out" } });
// tl.to(".text", { y: "0%", duration: 1, stagger: 0.25 });
tl.to(".slider", { y: "-100%", duration: 1.5, delay: 0 });
tl.to(".intro", { y: "-100%", duration: 1 }, "-=1");
tl.fromTo(
"nav",
{ background: "black", visibility: "hidden", opacity: 0 },
{
// background: "black",
width: "100%",
visibility: "visible",
opacity: 1,
duration: 0.5,
}
);
tl.fromTo(".big-text", { opacity: 0 }, { opacity: 1, duration: 1 }, "-=1");
const cool = new fullpage("#fullpage", {
autoScrolling: true,
navigation: true,
onLeave: (origin, destination, direction) => {
const come = origin.item.id;
dest.push(come);
const header = document.querySelector(".header");
const colors = ["#8d7676", "#2d2c2c", "#1b1b1b"];
const section = destination.item.id;
console.log(section);
place.push(`${section}`);
switch (section) {
case "home":
header.style.background = colors[2];
break;
case "about":
tl.to("nav", {
background: "none",
});
header.style.background = colors[1];
break;
case "Downloads":
tl.to("nav", {
background: "none",
});
header.style.background = colors[0];
default:
break;
}
},
});
}
function buttons() {
const ul = document.querySelector(".nav-links");
const btns = [ul.querySelectorAll("button")][0];
const autoNav = document.querySelector("#fp-nav");
moreHardStuff(btns);
hardStuff(autoNav, dest, btns, place);
}
function hardStuff(autoNav, origin, btns, place) {
const lies = document.querySelectorAll("a");
lies[1].id = "hme";
lies[2].id = "abut";
lies[3].id = "down";
btns.forEach((element) => {
element.addEventListener("click", () => {
// // console.log(origin, place);
// if (dest.includes("about")) {
// lies[2].className = "";
// console.log("working!");
// if (place.includes("home")) {
// lies[2].className = "";
// lies[3].className = "";
// lies[1].className = "active";
// }
// // if ((place[0] = "Downloads")) {
// // lies[3].className = "active";
// // lies[2].className = "";
// // lies[1].className = "";
// // }
// }
place = [];
dest = [];
});
});
}
function moreHardStuff(btns) {
const lies = document.querySelectorAll("a");
btns[0].addEventListener("click", () => {
const div = document.querySelector("#fullpage");
document.body.className = "fp-viewing-0";
div.style =
"height: 100%; position: relative; touch-action: none; transform: translate3d(0px, 0px, 0px); transition: all 700ms ease 0s;";
if (place.includes("about")) {
if (dest.includes("home")) {
lies[1].className = "active";
lies[2].className = "";
lies[3].className = "";
console.log("working!");
place.length = 0;
dest.length = 0;
}
}
});
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
main {
font-family: "Amiri", sans-serif;
}
.landing {
min-height: 100vh;
background: linear-gradient(to bottom, #1b1b1b, #2c2b2b);
background-size: cover;
padding: 0rem 5rem;
}
nav {
display: flex;
align-items: center;
width: 90%;
margin: auto;
justify-content: space-between;
min-height: 10vh;
}
.nav-links {
display: flex;
list-style: none;
}
.nav-links button {
display: inline;
border: none;
background: none;
color: white;
padding: 2.5rem;
font-size: 1.2rem;
}
#logo {
font-family: "Cairo", cursive;
font-weight: lighter;
color: white;
font-size: 2rem;
}
.big-text {
border: none;
background: none;
color: white;
position: absolute;
top: 40%;
left: 52%;
transform: translate(-60%, -39%);
font-size: 3rem;
font-family: "Montserrat", sans-serif;
}
.intro {
background: black;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.slider {
background: rgb(64, 89, 112);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform: translateY(100%);
}
.intro-text {
color: rgb(224, 236, 247);
font-family: "Amiri", sans-serif;
font-size: 3rem;
}
.hide {
background: black;
overflow: hidden;
}
.hide span {
transform: translateY(100%);
display: inline-block;
}
#about {
background: linear-gradient(to bottom, #2c2b2b, #583a3aaf);
}
#Downloads {
background: linear-gradient(to bottom, #583a3aaf, #c74848);
}
.header {
position: sticky;
z-index: 10;
transition: all 1s ease;
top: 0px;
background: rgb(64, 89, 112);
/* background: linear-gradient(to left, #405970, #304558); */
}
nav h1 {
margin-left: 2rem;
}
nav h1,
nav button {
flex: 1;
}
#about {
color: white;
align-items: center;
justify-content: center;
padding: 1rem;
}
#about h1 {
margin-top: -15rem;
font-size: 2.7rem;
margin-left: 25rem;
}
#about p {
margin-top: 10rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/3.0.9/fullpage.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/3.0.9/fullpage.min.css" rel="stylesheet"/>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Hello!</title>
<link rel="stylesheet" href="resources/fullpage.min.css" />
<script src="resources/fullpage.min.js"></script>
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link
href="https://fonts.googleapis.com/css2?family=Cairo:wght#700&display=swap"
rel="stylesheet"
/>
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link
href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght#1,900&display=swap"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/css2?family=Amiri&display=swap"
rel="stylesheet"
/>
</head>
<body>
<header class="header">
<nav>
<h1 id="logo">Hello!</h1>
<ul class="nav-links">
<button>Home</button>
<button>About</button>
<button>Downloads</button>
</ul>
</nav>
</header>
<div id="fullpage">
<section id="home" class="section s1">
<main>
<section class="landing">
<button
id="home"
type="submit"
onclick="window.location.href='./projects/index.html' "
class="big-text"
>
Projects!
</button>
</section>
</main>
<div class="intro">
<!-- <div class="intro-text">
<h1 class="hide">
<span class="text">Hello!</span>
</h1>
<h1 class="hide">
<span class="text">How Are You?</span>
</h1>
<h1 class="hide">
<span class="text">Im Fine.</span>
</h1>
</div> -->
</div>
<div class="slider"></div>
</section>
<section id="about" class="section s2">
<h1 class="about">About</h1>
<p></p>
</section>
<section id="Downloads" class="section s3">
Google!
</section>
</div>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"
integrity="sha512-IQLehpLoVS4fNzl7IfH8Iowfm5+RiMGtHykgZJl9AWMgqx0AmJ6cRWcB+GaGVtIsnC4voMfm8f2vwtY+6oPjpQ=="
crossorigin="anonymous"
></script>
<script src="web.js"></script>
</body>
</html>

Below is what I could make out of your question.
I rectified the scroll problem of second and third page as you mentioned above and made the navbar buttons respond to the scrollTo function of fullpage.js
If you aren't familiar with the properties of fullpage.js
visit this
document.body.onload = function() {
document.getElementById('home_btn').click();
}
var place = [];
animationsAndOther();
function animationsAndOther() {
const tl = gsap.timeline({
defaults: {
ease: "power1.out"
}
});
// tl.to(".text", { y: "0%", duration: 1, stagger: 0.25 });
tl.to(".slider", {
y: "-100%",
duration: 1.5,
delay: 0
});
tl.to(".intro", {
y: "-100%",
duration: 1
}, "-=1");
tl.fromTo(
"nav", {
background: "black",
visibility: "hidden",
opacity: 0
}, {
// background: "black",
width: "100%",
visibility: "visible",
opacity: 1,
duration: 0.5,
}
);
tl.fromTo(".big-text", {
opacity: 0
}, {
opacity: 1,
duration: 1
}, "-=1");
}
const cool = new fullpage("#fullpage", {
autoScrolling: true,
navigation: true,
anchors: ['hme', 'abt', 'down'],
navigationTooltips: ['Home', 'About', 'Downloads']
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
main {
font-family: "Amiri", sans-serif;
}
.landing {
min-height: 100vh;
background: linear-gradient(to bottom, #1b1b1b, #2c2b2b);
background-size: cover;
padding: 0rem 5rem;
}
nav {
display: flex;
align-items: center;
width: 90%;
margin: auto;
justify-content: space-between;
min-height: 10vh;
}
.nav-links {
display: flex;
list-style: none;
}
.nav-links a {
float: right;
display: inline;
border: none;
background: none;
color: white;
padding: 2.5rem;
font-size: 1.2rem;
text-decoration: none;
font-family: 'arial';
}
#logo {
font-family: "Cairo", cursive;
font-weight: lighter;
color: white;
font-size: 2rem;
}
.big-text {
border: none;
background: none;
color: white;
position: absolute;
top: 40%;
left: 52%;
transform: translate(-60%, -39%);
font-size: 3rem;
font-family: "Montserrat", sans-serif;
}
.intro {
background: black;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.slider {
background: rgb(64, 89, 112);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform: translateY(100%);
}
.intro-text {
color: rgb(224, 236, 247);
font-family: "Amiri", sans-serif;
font-size: 3rem;
}
.hide {
background: black;
overflow: hidden;
}
.hide span {
transform: translateY(100%);
display: inline-block;
}
#about {
background: linear-gradient(to bottom, #2c2b2b, #583a3aaf);
}
#Downloads {
background: linear-gradient(to bottom, #583a3aaf, #c74848);
}
.header {
position: fixed;
z-index: 10;
transition: all 1s ease;
top: 0px;
width: 100%;
background: rgb(64, 89, 112);
/* background: linear-gradient(to left, #405970, #304558); */
}
nav h1 {
margin-left: 2rem;
}
nav h1,
nav a {
flex: 1;
}
#about {
color: white;
align-items: center;
justify-content: center;
padding: 1rem;
}
#about h1 {
margin-top: -15rem;
font-size: 2.7rem;
margin-left: 25rem;
}
#about p {
margin-top: 10rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/3.0.9/fullpage.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/3.0.9/fullpage.min.css" rel="stylesheet" />
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Hello!</title>
<link rel="stylesheet" href="resources/fullpage.min.css" />
<script src="resources/fullpage.min.js"></script>
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght#700&display=swap" rel="stylesheet" />
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght#1,900&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Amiri&display=swap" rel="stylesheet" />
</head>
<body>
<header class="header">
<nav>
<h1 id="logo">Hello!</h1>
<ul class="nav-links">
Home
About
Downloads
</ul>
</nav>
</header>
<div id="fullpage">
<section id="home" class="section s1">
<main>
<section class="landing">
<button id="home" type="submit" onclick="window.location.href='./projects/index.html' " class="big-text">
Projects!
</button>
</section>
</main>
<div class="intro">
<div class="intro-text">
<h1 class="hide">
<span class="text">Hello!</span>
</h1>
<h1 class="hide">
<span class="text">How Are You?</span>
</h1>
<h1 class="hide">
<span class="text">Im Fine.</span>
</h1>
</div>
</div>
<div class="slider"></div>
</section>
<section id="about" class="section s2">
<h1 class="about">About</h1>
<p></p>
</section>
<section id="Downloads" class="section s3">
Google!
</section>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js" integrity="sha512-IQLehpLoVS4fNzl7IfH8Iowfm5+RiMGtHykgZJl9AWMgqx0AmJ6cRWcB+GaGVtIsnC4voMfm8f2vwtY+6oPjpQ==" crossorigin="anonymous"></script>
<script src="web.js"></script>

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);

Why is the animation not reversed in GSAP?

I have question, I wanted reverse animation showMenuList (this is pink background), but this not working, where is the mistake? I tried paused, and so many method but this not working, please help
I know that this is mostly code but I don't know what else to write. Find my code below and here a Codepen link.
const menuToggler = document.querySelector(".toggler");
const menuTogglerHamburger = document.querySelector(".toggler .hamburger");
menuToggler.addEventListener("click", function () {
//checking if there is a class animationToggler
if (menuTogglerHamburger.classList.contains("animationToggler")) {
//restart animation rotate
menuTogglerHamburger.classList.remove("animationToggler");
void menuTogglerHamburger.offsetWidth;
menuTogglerHamburger.classList.add("animationToggler");
}
menuTogglerHamburger.classList.add("animationToggler");
menuToggler.classList.toggle("show");
menuToggler.classList.contains("show")
? showMenuList(true)
: showMenuList(false);
setTimeout(() => {
//animation line on the cross
menuTogglerHamburger.classList.toggle("active");
}, 200);
});
//---------------------- Show menu list ----------------------//
const showMenuList = (e) => {
console.log(e);
const showMenuTl = gsap.timeline({ pause: true });
e ? showMenuTl.play() : showMenuTl.reverse();
showMenuTl
.to(".nav-menu", 0.8, { css: { top: "50%" } })
.to(".nav-menu", 0.4, { css: { width: "140vw", height: "140vw" } });
};
body {
overflow: hidden;
}
nav {
display: flex;
width: 100%;
align-items: center;
justify-content: space-around;
padding-top: 1em;
}
.toggler {
display: flex;
align-items: center;
cursor: pointer;
}
.animationToggler {
animation: animationTogglerMenu .8s ease;
}
.toggler p {
margin: 0;
text-transform: uppercase;
font-size: 1.65rem;
margin: 0 0 0 10px;
z-index: 3;
}
.hamburger {
z-index: 3;
}
.hamburger .line {
height: 4px;
width: 2.5em;
background: #000;
margin: .45em 0;
border-radius: 50px;
transition: .3s;
}
.active .one {
transform: rotate(45deg) translateY(15px);
}
.active .two {
background-color: transparent;
transition: none;
}
.active .three {
transform: rotate(-45deg) translateY(-15px);
}
.nav-menu {
position: absolute;
top: -100%;
left: 50%;
transform: translate(-50%, -50%);
width: 3em;
height: 3em;
background-color: rgb(255, 117, 117);
border-radius: 50%;
/* opacity: 0.4; */
z-index: 2;
}
.nav-menu ul {
display: none;
}
#keyframes animationTogglerMenu {
100% {
transform: rotate(360deg);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="toggler">
<div class="hamburger">
<div class="line one"></div>
<div class="line two"></div>
<div class="line three"></div>
</div>
<p>Menu</p>
</div>
<div class="nav-menu">
<ul>
<li>Home</li>
<li>Projekty</li>
<li>O nas</li>
<li>Kontakt</li>
</ul>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
<script src="main.js"></script>
</body>
</html>
One issue with your code is you need to pass paused: true instead of pause:true to the timeline function.
One way you could improve your code (in my opinion) is to move the creation of your timeline object to the top level of your code block. Like so...
const menuToggler = document.querySelector(".toggler");
const menuTogglerHamburger = document.querySelector(".toggler .hamburger");
// Add it here -----------------------
const showMenuTl = gsap.timeline({ paused: true });
showMenuTl
.to(".nav-menu", 0.8, { css: { top: "50%" } })
.to(".nav-menu", 0.4, { css: { width: "140vw", height: "140vw" } });
Then you can get rid of the showMenuList function and call play and reverse directly.
menuToggler.classList.toggle("show");
menuToggler.classList.contains("show")
? showMenuTl.play()
: showMenuTl.reverse()
First, it should be { paused: true }, not { pause: true }, as #jessegavin said. Second, at the point where the click happens, you should have already set up the animation, which means the timeline definition should be at the top, outside of showMenuList. Third, you could simplify your code (See the JavaScript part, it's way more short, I slightly modified the CSS). Like so:
const menuToggler = document.querySelector(".toggler");
const showMenuTl = gsap.timeline({ paused: true });
showMenuTl
.to(".nav-menu", 0.8, { css: { top: "50%" } })
.to(".nav-menu", 0.4, { css: { width: "140vw", height: "140vw" } });
menuToggler.addEventListener("click", function () {
if (menuToggler.classList.contains("active")) {
menuToggler.classList.remove("active");
showMenuTl.reverse();
} else {
menuToggler.classList.add("active");
showMenuTl.play();
}
});
body {
overflow: hidden;
}
nav {
display: flex;
width: 100%;
align-items: center;
justify-content: space-around;
padding-top: 1em;
}
.toggler {
display: flex;
align-items: center;
cursor: pointer;
}
.toggler p {
margin: 0;
text-transform: uppercase;
font-size: 1.65rem;
margin: 0 0 0 10px;
z-index: 3;
}
.hamburger {
z-index: 3;
}
.hamburger .line {
height: 4px;
width: 2.5em;
background: #000;
margin: 0.45em 0;
border-radius: 50px;
transition: 0.3s;
}
.active .hamburger {
animation: animationTogglerMenu 0.8s ease;
}
.active .one {
transform: rotate(45deg) translateY(15px);
}
.active .two {
background-color: transparent;
transition: none;
}
.active .three {
transform: rotate(-45deg) translateY(-15px);
}
.nav-menu {
position: absolute;
top: -100%;
left: 50%;
transform: translate(-50%, -50%);
width: 3em;
height: 3em;
background-color: rgb(255, 117, 117);
border-radius: 50%;
/* opacity: 0.4; */
z-index: 2;
}
.nav-menu ul {
display: none;
}
#keyframes animationTogglerMenu {
100% {
transform: rotate(360deg);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="toggler">
<div class="hamburger">
<div class="line one"></div>
<div class="line two"></div>
<div class="line three"></div>
</div>
<p>Menu</p>
</div>
<div class="nav-menu">
<ul>
<li>Home</li>
<li>Projekty</li>
<li>O nas</li>
<li>Kontakt</li>
</ul>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
<script src="main.js"></script>
</body>
</html>
One way you could approach this is creating another timeline. Which would be annoying to deal with if you added more keyframes. Another way you could do this is by adding a starting keyframe and then everything should run smoothly as shown below.
showMenuTl
.to(".nav-menu", 1, { css: { width: "3rem", height: "3rem", top: "-100%" } })
.to(".nav-menu", 0.8, { css: { width: "3rem", height: "3rem", top: "50%" } })
.to(".nav-menu", 0.4, { css: { width: "140vw", height: "140vw", top: "50%" } });
e ? showMenuTl.play() : showMenuTl.reverse(0);

The changing volume icon pushes the volume slider. css problem

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

How to remove a div after it has faded out (Vanilla JS)

I have a problem with a transition in JS. What i want is that once the div has opacity 0, js remove it automatically. The problem is that, i have to exit the div area, and then it removes it. That is because i have a mouseleave, but my question is. How can i delete that div without my mouse leaving the div area? Here's the CodePen link:
https://codepen.io/SpeedItaly/pen/PoGPGJZ
function style() {
h4 = document.getElementById("hover_me");
header = document.getElementById("header");
logo = document.getElementById("hover_me1");
logo.addEventListener("mouseover", (e) => {
logo.style.transition = "1200ms ease-in-out opacity"
logo.style.opacity = "0"
});
logo.addEventListener("mouseleave", (e) => {
header.removeChild(logo);
});
menu = document.getElementById("menu");
if (logo.style.opacity == 0) {
menu.style.transition = "1200ms ease-in-out opacity"
menu.style.opacity = "1"
}
}
style();
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
height: 100%;
}
body {
background: #f4f4f4;
font-size: 16px;
font-family: "Inter";
font-weight: 400;
color: #fff;
}
.header {
width: 100%;
height: 100vh;
background: #222831;
}
.logo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #222831;
z-index: 99;
cursor: default;
}
.logo>h4 {
font-size: 70px;
}
.menu {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
transform: translate(0%, -50%);
opacity: 0;
}
.menu>li {
display: inline-block;
margin-left: 5px;
margin-right: 5px;
}
.menu>li>a {
text-decoration: none;
font-size: 25px;
text-transform: uppercase;
font-weight: 200;
color: #fff;
}
.menu>li>a:hover {
color: rgba(255, 255, 255, .35);
}
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght#100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
<body>
<!-- Start Header -->
<header class="header" id="header">
<!-- Start Logo Container -->
<div class="logo" id="hover_me1">
<h4 class="text_white" id="hover_me">SpeedItaly</h4>
</div>
<!-- End Logo Container -->
<!-- Start Menu -->
<ul class="menu" id="menu">
<li><a class="text_white" href="home.html">Home</a></li>
<li><a class="text_white" href="#">About</a></li>
<li><a class="text_white" href="#">Content</a></li>
</ul>
<!-- End Menu-->
</header>
<!-- End Header -->
You can use the transitionend event instead.
function style() {
h4 = document.getElementById("hover_me");
header = document.getElementById("header");
logo = document.getElementById("hover_me1");
logo.addEventListener("mouseover", (e) => {
logo.style.transition = "1200ms ease-in-out opacity"
logo.style.opacity = "0"
});
logo.addEventListener("transitionend", (e) => {
header.removeChild(logo);
});
menu = document.getElementById("menu");
if (logo.style.opacity == 0) {
menu.style.transition = "1200ms ease-in-out opacity"
menu.style.opacity = "1"
}
}
style();
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
height: 100%;
}
body {
background: #f4f4f4;
font-size: 16px;
font-family: "Inter";
font-weight: 400;
color: #fff;
}
.header {
width: 100%;
height: 100vh;
background: #222831;
}
.logo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #222831;
z-index: 99;
cursor: default;
}
.logo>h4 {
font-size: 70px;
}
.menu {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
transform: translate(0%, -50%);
opacity: 0;
}
.menu>li {
display: inline-block;
margin-left: 5px;
margin-right: 5px;
}
.menu>li>a {
text-decoration: none;
font-size: 25px;
text-transform: uppercase;
font-weight: 200;
color: #fff;
}
.menu>li>a:hover {
color: rgba(255, 255, 255, .35);
}
<head>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght#100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
</head>
<body>
<!-- Start Header -->
<header class="header" id="header">
<!-- Start Logo Container -->
<div class="logo" id="hover_me1">
<h4 class="text_white" id="hover_me">SpeedItaly</h4>
</div>
<!-- End Logo Container -->
<!-- Start Menu -->
<ul class="menu" id="menu">
<li><a class="text_white" href="home.html">Home</a></li>
<li><a class="text_white" href="#">About</a></li>
<li><a class="text_white" href="#">Content</a></li>
</ul>
<!-- End Menu-->
</header>
<!-- End Header -->
Just use a setTimeout. Specifically, setTimeout(function() {header.removeChild(logo)},1200).
function style() {
h4 = document.getElementById("hover_me");
header = document.getElementById("header");
logo = document.getElementById("hover_me1");
logo.addEventListener("mouseover", (e) => {
logo.style.transition = "1200ms ease-in-out opacity"
logo.style.opacity = "0"
setTimeout(function() {header.removeChild(logo)},1200)
});
menu = document.getElementById("menu");
if (logo.style.opacity == 0) {
menu.style.transition = "1200ms ease-in-out opacity"
menu.style.opacity = "1"
}
}
style();
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
height: 100%;
}
body {
background: #f4f4f4;
font-size: 16px;
font-family: "Inter";
font-weight: 400;
color: #fff;
}
.header {
width: 100%;
height: 100vh;
background: #222831;
}
.logo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #222831;
z-index: 99;
cursor: default;
}
.logo>h4 {
font-size: 70px;
}
.menu {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
transform: translate(0%, -50%);
opacity: 0;
}
.menu>li {
display: inline-block;
margin-left: 5px;
margin-right: 5px;
}
.menu>li>a {
text-decoration: none;
font-size: 25px;
text-transform: uppercase;
font-weight: 200;
color: #fff;
}
.menu>li>a:hover {
color: rgba(255, 255, 255, .35);
}
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght#100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
<body>
<!-- Start Header -->
<header class="header" id="header">
<!-- Start Logo Container -->
<div class="logo" id="hover_me1">
<h4 class="text_white" id="hover_me">SpeedItaly</h4>
</div>
<!-- End Logo Container -->
<!-- Start Menu -->
<ul class="menu" id="menu">
<li><a class="text_white" href="home.html">Home</a></li>
<li><a class="text_white" href="#">About</a></li>
<li><a class="text_white" href="#">Content</a></li>
</ul>
<!-- End Menu-->
</header>
<!-- End Header -->
You can use the following code to receive your current browser's Transition Events:
const getTransitionEvents = () => {
let t,
el = document.createElement("fakeelement");
let transitions = {
transition: {
Start: "transitionstart",
Run: "transitionrun",
Cancel: "transitioncancel",
End: "transitionend"
},
OTransition: {
Start: "oTransitionStart",
Run: "oTransitionRun",
Cancel: "oTransitionCancel",
End: "oTransitionEnd"
},
MozTransition: {
Start: "transitionstart",
Run: "transitionrun",
Cancel: "transitioncancel",
End: "transitionend"
},
WebkitTransition: {
Start: "webkitTransitionStart",
Run: "webkitTransitionRun",
Cancel: "webkitTransitionCancel",
End: "webkitTransitionEnd"
}
};
for (t in transitions) {
if (el.style[t] !== undefined) {
return transitions[t];
}
}
};
After that you can just bind the return of this function to a variable
const transEvt = getTransitionEvents();
and bind eventListeners to it
document.addEventListener(transEvt.End, (evt) => {
// do some cool stuff when the Transition ends
});
I use this myself, in a #just-for-fun #work-in-progress pen called Simple Image Loop without duplicating slides where I rearrange the slides after the transform transition has ended.
You can listen for the transitionend CSS event, and remove the node in it.
Also, it is very recommended to declare your variables and move CSS declarations into the CSS code, where possible.
function style() {
const h4 = document.getElementById("hover_me");
const header = document.getElementById("header");
const logo = document.getElementById("hover_me1");
const menu = document.getElementById("menu")
logo.addEventListener("mouseover", (e) => {
logo.classList.add("hidden")
logo.addEventListener("transitionend", () => {
logo.remove()
menu.classList.remove("hidden")
})
});
}
style();
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
height: 100%;
}
body {
background: #f4f4f4;
font-size: 16px;
font-family: "Inter";
font-weight: 400;
color: #fff;
}
.header {
width: 100%;
height: 100vh;
background: #222831;
}
.logo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #222831;
z-index: 99;
cursor: default;
transition: 1200ms ease-in-out opacity;
}
.logo>h4 {
font-size: 70px;
}
.menu {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
transform: translate(0%, -50%);
transition: 1200ms ease-in-out opacity;
}
.menu>li {
display: inline-block;
margin-left: 5px;
margin-right: 5px;
}
.menu>li>a {
text-decoration: none;
font-size: 25px;
text-transform: uppercase;
font-weight: 200;
color: #fff;
}
.menu>li>a:hover {
color: rgba(255, 255, 255, .35);
}
.hidden{
opacity: 0;
}
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght#100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
<body>
<!-- Start Header -->
<header class="header" id="header">
<!-- Start Logo Container -->
<div class="logo" id="hover_me1">
<h4 class="text_white" id="hover_me">SpeedItaly</h4>
</div>
<!-- End Logo Container -->
<!-- Start Menu -->
<ul class="menu hidden" id="menu">
<li><a class="text_white" href="home.html">Home</a></li>
<li><a class="text_white" href="#">About</a></li>
<li><a class="text_white" href="#">Content</a></li>
</ul>
<!-- End Menu-->
</header>
<!-- End Header -->

Categories

Resources