Home > Blockchain >  Web button only works once, then I have to refresh page
Web button only works once, then I have to refresh page

Time:06-22

I'm a bit new to web development. As my first project with JS, I decided to create a simple button, on which if someone clicks, it shows a custom popup. But the thing is after closing the popup window, I have to refresh the page to click the button again.

Here is my code so far:

const btn = document.querySelector('.btn');
const cloBtn = document.querySelector('.close');
const popUp = document.querySelector('.popup');
const overlay = document.querySelector('.overlay');

btn.addEventListener('click', () => {
  popUp.classList.add('open');
  overlay.classList.add('overlay-open');

});

cloBtn.addEventListener('click', () => {
  popUp.classList.add('popClose');
  overlay.classList.add('overlay-close');

})
body {
  margin: 0%;
}

.btn {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

button {
  border: none;
  cursor: pointer;
}

.btn button {
  background-color: blue;
  padding: 15px 45px 15px 45px;
  font-size: large;
  font-weight: 700;
  color: rgb(255, 255, 255);
  border-radius: 10px;
}

.popup {
  width: 300px;
  background-color: rgb(228, 228, 228);
  height: 150px;
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
  gap: 15px;
  border-radius: 10px;
  z-index: 5;
  position: absolute;
  top: 30%;
  left: 50%;
  transform: scale(1) translate(-50%, -50%);
  visibility: hidden;
}

.popup button {
  background-color: rgb(255, 0, 55);
  padding: 10px 30px 10px 30px;
  font-size: medium;
  font-weight: 700;
  color: rgb(0, 0, 0);
  border-radius: 10px;
}

.overlay {
  height: 100%;
  width: 100%;
  background-color: rgba(133, 131, 131, 0.555);
  position: absolute;
  z-index: 2;
  visibility: hidden;
}

.overlay-open {
  visibility: visible;
}

.overlay-close {
  visibility: hidden;
}

.open {
  visibility: visible;
  animation: boxPop 0.3s ease-in;
}

@keyframes boxPop {
  from {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
  }
  to {
    position: absolute;
    top: 30%;
    left: 50%;
    transform: scale(1) translate(-50%, -50%);
  }
}

.popClose {
  animation: boxClo 0.3s ease-in;
  transform: translate(-50%, -50%) scale(0);
}

@keyframes boxClo {
  from {
    position: absolute;
    top: 30%;
    left: 50%;
    transform: scale(1) translate(-50%, -50%);
  }
  to {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>

<body>
  <div ><button>Press Me</button></div>
  <div >
    <div >Hello Nice to Meet You!</div>
    <div ><button>Close</button></div>
  </div>
  <div ></div>

  <script src="app.js"></script>
</body>

</html>

CodePudding user response:

The issue is, that both button presses adding a class but not removing the counter class. Simplest solution would be the usage of toggle. In that case you can bind the same eventListener to both buttons and shorten the JS code drastically:

const btn = document.querySelectorAll('.btn');
const popUp = document.querySelector('.popup');
const overlay = document.querySelector('.overlay');

btn.forEach(el => el.addEventListener('click', () => {
  popUp.classList.toggle('open');
  overlay.classList.toggle('overlay-open');
}));
body {
  margin: 0%;
}

.btn {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

button {
  border: none;
  cursor: pointer;
}

.btn button {
  background-color: blue;
  padding: 15px 45px 15px 45px;
  font-size: large;
  font-weight: 700;
  color: rgb(255, 255, 255);
  border-radius: 10px;
}

.popup {
  width: 300px;
  background-color: rgb(228, 228, 228);
  height: 150px;
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
  gap: 15px;
  border-radius: 10px;
  z-index: 5;
  position: absolute;
  top: 30%;
  left: 50%;
  transform: scale(1) translate(-50%, -50%);
  visibility: hidden;
}

.popup button {
  background-color: rgb(255, 0, 55);
  padding: 10px 30px 10px 30px;
  font-size: medium;
  font-weight: 700;
  color: rgb(0, 0, 0);
  border-radius: 10px;
}

.overlay {
  height: 100%;
  width: 100%;
  background-color: rgba(133, 131, 131, 0.555);
  position: absolute;
  z-index: 2;
  visibility: hidden;
}

.overlay-open {
  visibility: visible;
}

.overlay-close {
  visibility: hidden;
}

.open {
  visibility: visible;
  animation: boxPop 0.3s ease-in;
}

@keyframes boxPop {
  from {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
  }
  to {
    position: absolute;
    top: 30%;
    left: 50%;
    transform: scale(1) translate(-50%, -50%);
  }
}

.popClose {
  animation: boxClo 0.3s ease-in;
  transform: translate(-50%, -50%) scale(0);
}

@keyframes boxClo {
  from {
    position: absolute;
    top: 30%;
    left: 50%;
    transform: scale(1) translate(-50%, -50%);
  }
  to {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>

<body>
  <div ><button>Press Me</button></div>
  <div >
    <div >Hello Nice to Meet You!</div>
    <div ><button>Close</button></div>
  </div>
  <div ></div>

  <script src="app.js"></script>
</body>

</html>

CodePudding user response:

It's because you are adding open and overlay-open classes and never removing them. So after hitting close, you have open and popClose on <div >, and overlay-open and overlay-close on <div >.

And CSS specificity makes that the second classes apply. You could do as below, having 2 classes instead of 4. You just need open and overlay-open.

const btn= document.querySelector('.btn');
const cloBtn=document.querySelector('.close');
const popUp=document.querySelector('.popup');
const overlay=document.querySelector('.overlay');

btn.addEventListener('click',()=>{
    popUp.classList.add('open'); 
    overlay.classList.add('overlay-open'); 
    
 });

 cloBtn.addEventListener('click',()=>{
    popUp.classList.remove('open'); 
    overlay.classList.remove('overlay-open'); 
   
})
body{
margin: 0%;

}

.btn{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50% ,-50%);
}

button{
    border: none;
    cursor: pointer;
}

.btn button{
    background-color: blue;
    padding: 15px 45px 15px 45px;
    font-size: large;
    font-weight: 700;
    color: rgb(255, 255, 255);
    border-radius: 10px;
}

.popup{
    width: 300px;
    background-color: rgb(228, 228, 228);
    height: 150px;
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    gap: 15px;
    border-radius:10px ;
    z-index: 5;
    position: absolute;
    top: 30%;
    left: 50%;
    transform:scale(1) translate(-50% ,-50%);
    visibility: hidden;
}

.popup button{
    background-color: rgb(255, 0, 55);
    padding: 10px 30px 10px 30px;
    font-size: medium;
    font-weight: 700;
    color: rgb(0, 0, 0);
    border-radius: 10px;
}

.overlay{
    height: 100%;
    width: 100%;
    background-color: rgba(133, 131, 131, 0.555);
    position: absolute;
    z-index: 2;
    visibility: hidden;
}

.overlay-open{
    visibility: visible;
}
/*
.overlay-close{
    visibility: hidden;
}*/

.open{
    visibility: visible;
   animation: boxPop 0.3s ease-in;
}

@keyframes boxPop {
    from {
        position: absolute;
        top: 50%;
        left: 50%;
        transform:translate(-50% ,-50%) scale(0);
    }
  to {
    position: absolute;
    top: 30%;
    left: 50%;
    transform:scale(1) translate(-50% ,-50%);
  }
}
/*
.popClose{
    animation: boxClo 0.3s ease-in;
    transform:translate(-50% ,-50%) scale(0);
}*/

@keyframes boxClo {
    from {
        position: absolute;
    top: 30%;
    left: 50%;
    transform:scale(1) translate(-50% ,-50%);
        
    }
  to {
    position: absolute;
        top: 50%;
        left: 50%;
        transform:translate(-50% ,-50%) scale(0);
  }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Document</title>
</head>
<body>
    <div ><button>Press Me</button></div>
<div >
    <div >Hello Nice to Meet You!</div>
    <div ><button>Close</button></div>
</div>
<div ></div>

    <script src="app.js"></script>
</body>
</html>

CodePudding user response:

You have to remove old class after each function execution to work it properly.

const btn= document.querySelector('.btn');
const cloBtn=document.querySelector('.close');
const popUp=document.querySelector('.popup');
const overlay=document.querySelector('.overlay');

btn.addEventListener('click',()=>{
    popUp.classList.add('open'); 
    overlay.classList.add('overlay-open'); 
    popUp.classList.remove('popClose');
    overlay.classList.remove('overlay-close')
    
 });

 cloBtn.addEventListener('click',()=>{
        popUp.classList.remove('open'); 
        overlay.classList.remove('overlay-open');
        popUp.classList.add('popClose');
        overlay.classList.add('overlay-close');
   
})
body{
margin: 0%;

}

.btn{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50% ,-50%);
}

button{
    border: none;
    cursor: pointer;
}

.btn button{
    background-color: blue;
    padding: 15px 45px 15px 45px;
    font-size: large;
    font-weight: 700;
    color: rgb(255, 255, 255);
    border-radius: 10px;
}

.popup{
    width: 300px;
    background-color: rgb(228, 228, 228);
    height: 150px;
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    gap: 15px;
    border-radius:10px ;
    z-index: 5;
    position: absolute;
    top: 30%;
    left: 50%;
    transform:scale(1) translate(-50% ,-50%);
    visibility: hidden;
}

.popup button{
    background-color: rgb(255, 0, 55);
    padding: 10px 30px 10px 30px;
    font-size: medium;
    font-weight: 700;
    color: rgb(0, 0, 0);
    border-radius: 10px;
}

.overlay{
    height: 100%;
    width: 100%;
    background-color: rgba(133, 131, 131, 0.555);
    position: absolute;
    z-index: 2;
    visibility: hidden;
}

.overlay-open{
    visibility: visible;
}

.overlay-close{
    visibility: hidden;
}

.open{
    visibility: visible;
   animation: boxPop 0.3s ease-in;
}

@keyframes boxPop {
    from {
        position: absolute;
        top: 50%;
        left: 50%;
        transform:translate(-50% ,-50%) scale(0);
    }
  to {
    position: absolute;
    top: 30%;
    left: 50%;
    transform:scale(1) translate(-50% ,-50%);
  }
}

.popClose{
    animation: boxClo 0.3s ease-in;
    transform:translate(-50% ,-50%) scale(0);
}

@keyframes boxClo {
    from {
        position: absolute;
    top: 30%;
    left: 50%;
    transform:scale(1) translate(-50% ,-50%);
        
    }
  to {
    position: absolute;
        top: 50%;
        left: 50%;
        transform:translate(-50% ,-50%) scale(0);
  }
} 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Document</title>
</head>
<body>
    <div ><button>Press Me</button></div>
<div >
    <div >Hello Nice to Meet You!</div>
    <div ><button>Close</button></div>
</div>
<div ></div>

    <script src="app.js"></script>
</body>
</html>

  • Related