javascriptcss-animationsaddeventlistenerinfinite-loopreplay

Replaying CSS Animations


Been struggling hours now to find a solution for this. I´m kinda new to JS so this is kinda tricky for me. Was hoping someone here maybe had a bit of time to give me a solution. Thanks.

If you click on the question mark (top right) it starts my animation to show the slider, and when you click the X it starts an animation to hide the slider.

I would like this to happen infinite. So when X has been clicked and the slider goes in, you can just click on the question mark and the slider pops up again, and so forth.

let press = document.getElementById("questionClick");
let show = document.getElementById("show");
let showOpt = document.getElementById("showSecond")
let hide = document.getElementById("exit");
let arrow = document.getElementById("nextArrow");
let info = document.getElementsByClassName("info");




show.classList.remove("info");

press.addEventListener("click", function () {

    show.classList.add("info");
    arrow.style.opacity = "0"
    exit.style.opacity = "0"
    
    setTimeout(function() {
        exit.style.opacity = "100"
    }, (400));
    setTimeout(function() {
        arrow.style.opacity = "100"
    }, (1300));

}); 

hide.addEventListener("click", function () {

    showOpt.style.width = "0em"
    show.classList.add("infoExit");
    hide.style.opacity = "40%"
    setTimeout(function() {
        arrow.style.opacity = "0"
    }, (00));
    setTimeout(function() {
        exit.style.opacity = "0"
    }, (800));
    
});

  arrow.addEventListener("click", function() {

showOpt.style.width = "15em"
showOpt.style.height = "668px"
showOpt.style.padding = "1em"


  });










const resultEl = document.getElementById('result');
const lengthEl = document.getElementById('length');
const uppercaseEl = document.getElementById('uppercase');
const lowercaseEl = document.getElementById('lowercase');
const numbersEl = document.getElementById('numbers');
const symbolsEl = document.getElementById('symbols');
const generateEl = document.getElementById('generate');
const clipboard = document.getElementById('clipboard');



const randomFunc = {
    lower: getRandomLower,
    upper: getRandomUpper,
    number: getRandomNumber,
    symbol: getRandomSymbol
}

clipboard.addEventListener('click', () => {
    const textarea = document.createElement('textarea');
    const password = resultEl.innerText;
    
    if(!password) { return; }
    
    textarea.value = password;
    document.body.appendChild(textarea);
    textarea.select();
    document.execCommand('copy');
    textarea.remove();
    alert('Password copied to clipboard');
});

generate.addEventListener('click', () => {
    const length = +lengthEl.value;
    const hasLower = lowercaseEl.checked;
    const hasUpper = uppercaseEl.checked;
    const hasNumber = numbersEl.checked;
    const hasSymbol = symbolsEl.checked;
    
    resultEl.innerText = generatePassword(hasLower, hasUpper, hasNumber, hasSymbol, length);
});

function generatePassword(lower, upper, number, symbol, length) {
    let generatedPassword = '';
    const typesCount = lower + upper + number + symbol;
    const typesArr = [{lower}, {upper}, {number}, {symbol}].filter(item => Object.values(item)[0]);
    
    // Doesn't have a selected type
    if(typesCount === 0) {
        return '';
    }
    
    // create a loop
    for(let i=0; i<length; i+=typesCount) {
        typesArr.forEach(type => {
            const funcName = Object.keys(type)[0];
            generatedPassword += randomFunc[funcName]();
        });
    }
    
    const finalPassword = generatedPassword.slice(0, length);
    
    return finalPassword;
}


/* Generating random lower case characters */
function getRandomLower() {
    return String.fromCharCode(Math.floor(Math.random() * 26) + 97);
}

/* Generating random upper case characters */
function getRandomUpper() {
    return String.fromCharCode(Math.floor(Math.random() * 26) + 65);
}

/* Generating random numbers */
function getRandomNumber() {
    return +String.fromCharCode(Math.floor(Math.random() * 10) + 48);
}

/* Generating random symbols */
function getRandomSymbol() {
    const symbols = '!@#$%^&*(){}[]=<>/,.'
    return symbols[Math.floor(Math.random() * symbols.length)];
}
.info {
  animation: popup 1.6s;
  animation-fill-mode:forwards;
  }
 

@keyframes popup {

0% {
  white-space: nowrap;
  height: 4em;
  width: 0em;
  padding: 0.5em 1em 1em;
  opacity: 0;
  bottom: 13.9em; left: 9.7em; 
  color: rgba(0, 0, 0, 0);
}
40%, 50% {
  width: 14em;
  white-space: nowrap;
  color: rgba(0, 0, 0, 0.555);
  height: 4em;
  padding: 0.5em 1em 1em;
  opacity: 100;
  bottom: 14em; left: 16.5em
}
60% {
  white-space: normal;
  
}
90%, 100% {
  height: 668px ;
  width: 14em;
  opacity: 100;
  white-space: normal;
  bottom: 0; left: 16.5em
  
}
}

.infoExit {
  animation: popin 1.6s;
}

#exit {
  padding: .3em .3em 0 0;
  color: var(--clr-i-dim);
}
#exit:hover{
  color: var(--clr-minibtn-inactive);
}

@keyframes popin { 
0% {
  height: 668px ;
  width: 14em;
  white-space: normal;
  bottom: 0; left: 16.7em;
  opacity: 100;
}
40%, 50% {
  width: 14em;
  white-space: nowrap;
  height: 4em;
  padding: 0.5em 1em 1em;
  opacity: 100;
  bottom: 14em; left: 16.5em;
}
50% {
  white-space: nowrap;
  color: rgba(0, 0, 0, 0.555);
}
80%, 100% {
  white-space: nowrap;
  height: 4em;
  width: 0em;
  padding: 0.5em 0em 1em;
  opacity: 0;
  bottom: 13.9em; left: 9.7em; 
  color: rgba(0, 0, 0, 0);
}
}




#infohead {
    font-size: var(--fs-large);
    font-weight: var(--fw-primary);
    margin: 0.7em 0 0;
  }
  

#show {
  padding: 1em; 
  opacity: 0;
  height: 668px ; width: 12em;
  color: var(--txtclr-accent);
  cursor: pointer;
  font-size: var(--fs-info);
  background: linear-gradient(45deg, #83b7da , #958bbb);
  position: relative; left: 15.7em ; bottom: 0em; right: 0;
  overflow: hidden;  
  border-radius: 0 .5em .5em 0;
}



@import url(https://fonts.googleapis.com/css?family=Montserrat);
@import url("https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700");

:root {

    --ff-primary:  'Source Sans Pro', sans-serif;
    --ff-accent:  "Roboto", sans-serif;
    --ff-option: "Open Sans", sans-serif;
    --ff-number: 'Lato', sans-serif;

    --fw-primary: 600;
    --fw-accent: 400;

    --fs-nomal: 1.2rem; 
    --fs-info: 1.3em;
    --fs-large: 1.5rem; 

    --clr-primary:  #50a3a2;
    --clr-accent: #23235bdc;
    --clr-white: rgba(255, 255, 255, 0.8);
    
    --clr-btn: #530dc5;
    --clr-btn-hover: #7031d4;

    --clr-minibtn-hover: #4e694f;
    --clr-minibtn-inactive: #943f3f;

    --clr-shadow: 0px 5px 13px rgba(0, 0, 0, 0.993);
    --clr-bg-primary: #4f65dd;
    --clr-bg-accent: #aaa4a4 ;

    --clr-i-dim: rgba(28, 28, 31, 0.637);

    --txtclr-primary: rgba(255, 255, 255, 0.897);
    --txtclr-accent: #212121 ;

}

* {
    box-sizing: border-box;
}

html {

}

body {
  background: var(--clr-primary);
    color: var(--txtclr-primary);
    font-family: var(--ff-primary);

    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    min-height: 100vh;

    background: -webkit-linear-gradient(top left, var(--clr-bg-primary) 0%, #ffffff 100%);
    background: -moz-linear-gradient(top left, var(--clr-bg-primary)  0%, #ffffff 100%);
    background: -o-linear-gradient(top left, var(--clr-bg-primary)  0%, #ffffff  100%);
    background: linear-gradient(to bottom right, var(--clr-bg-primary)  0%, var(--clr-bg-accent)  100%); 
}


h2 {
    text-align: center; 
  margin: .2em 0 .8em;
}
h3 {
  background: var(--clr-white);
  color: var(--txtclr-accent);
  font-family: var(--ff-option);
  font-weight: var(--fw-accent);
  line-height: 2rem;
}
label {
    font-weight: var(--fw-primary);
    font-family: var(--ff-option);
}
li {
  margin: 1.8em 0;
  list-style: none;
}
input {
  cursor: pointer;
  font-family: var(--ff-primary);
}


.container {
    background: var(--clr-accent);
    box-shadow: var(--clr-shadow);
  position: absolute;
    padding: 2em;
    width:min(500px, 25em);
  height: 668px;
}

.setting {
    display: flex; justify-content: space-between; align-items: center;
}

.result-container {
    background-color: rgba(168, 162, 162, 0.4);
    display: flex; justify-content: flex-start; align-items: center;
    position: relative;
    font-size: var(--fs-nomal); letter-spacing: .14rem;
    padding: 1em .6em; margin: 0 0 0.3em;
    height: 2.6em;
}
.result-container #result {
    word-wrap: break-word;
}

.result-container .btn {
    font-size: 2rem;
    position: absolute; top: 0.15em; right: 0.15em;
    height: 1.3em; width: 1.3em;
}
.btn {
    background: var(--clr-btn);
    color: var(--txtclr-primary);
    cursor: pointer;
    border: none;
    font-size: var(--fs-nomal);
    padding: .6em;
}
.btn-large {
      display: block;
    width: 100%; height: 3.5em;
    transition: .6s; overflow: hidden;
    margin-top: 1.5em; border-radius: 4px;
    transform: translateX(0%) translateY(0%); 
}


#length {
  height: 2.5em; width: 12em;
  margin: 2em 0 1.7em; padding: 0 1em;
  outline: 0;
  
  color: var(--clr-bg-accent);
  border: 0; border-radius: 5px;

    outline: none;
    cursor: pointer;
}



/* ICONS */
#questionClick, #exit, #exitOpt {
  position: absolute; top: 0.3em; right: 0.3em;
}
#exit, #nextArrow {
  transition: .2s; opacity: 0;
  z-index: 999;
}
#nextArrow, #nextArrowOpt{
  position: absolute; bottom: .4em; right: .4em;
}
#nextArrowOpt {
  opacity: 100;
}
.far {
  position: relative; bottom: 0.55em; right: 0.25em;
}
/* ICONS */

@keyframes jump {
0% {
  top: 0.3em;
}
50% {
  top: 0.32em;
}
100% {
  top: 0.3em;
}

}

#showSecond {
  position: absolute; left: 15.7em ; bottom: 0em; right: 0;
  background: linear-gradient(45deg, #9fc4dd , #7d62dd);
  opacity: 100;
  white-space: normal;
  height: 0px ; width: 0em;
  cursor: pointer;
  font-size: var(--fs-nomal); line-height: 1.5em;
  position: relative; left: 19.2em ; bottom: 34.1em; right: 0;
  overflow: hidden;  
  border-radius: 0 .5em .5em 0 ;
  transition: 1s;
}




/* btn-large Effect */
button.btn-large:focus {
  outline: 0; 
}
button.btn-large:before {
  content: '';
  background: var(--clr-btn);
  opacity: .5; filter: blur(30px);
  transform: translateX(-100px) skewX(-15deg); 
}
button.btn-large:after {
  content: '';
  display: block; position: absolute;
  background: rgba(255, 255, 255, 0.2);
  width: 30px; height: 100%;
  left: 45px; top: 0;
  opacity: 0; filter: blur(5px);
  transform: translateX(-100px) skewX(-15deg); 
}
button.btn-large:hover {
  background: var(--clr-btn-hover);
}
button.btn-large:hover:before {
  transform: translateX(300px) skewX(-15deg);
  opacity: 0.6;
  transition: .7s; }
  button.btn-large:hover:after {
  transform: translateX(300px) skewX(-15deg);
  opacity: 1;
  transition: .7s; 
} /* btn-large Effect */


/* Mini button Effect */
.styled-checkbox {
  position: absolute;
  opacity: 100;
 }
  .styled-checkbox + label {
    position: relative;
    cursor: pointer;
    padding: 0;
    transition: 0.5s; }
  .styled-checkbox + label:before {
    content: '';
    display: inline-block; vertical-align: text-top;
    width: 20px; height: 20px;
    background: var(--clr-minibtn-inactive); }
  .styled-checkbox:hover + label:before {
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.342); 
     }
  .styled-checkbox:focus + label:before {
    box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12); }
  .styled-checkbox:checked + label:before {
    background: var(--clr-minibtn-hover); }
  .styled-checkbox:disabled + label {
    color: #b8b8b8;
    cursor: auto; }
  .styled-checkbox:disabled + label:before {
    box-shadow: none;
    background: #ddd; }
  .styled-checkbox:checked + label:after {
    content: '';
    position: absolute; left: 5px; top: 9px;
    width: 2px; height: 2px;
    background: white; box-shadow: 2px 0 0 white,
 4px 0 0 white, 
 4px -2px 0 white, 
 4px -4px 0 white,
 4px -6px 0 white, 
 4px -8px 0 white;
    transform: rotate(45deg); }
/* Mini button Effect */


.range {
  -webkit-appearance: none;
  background: none;
}

.range::-webkit-slider-runnable-track {
  background-color: #d7dbdd;
  height: 6px;
  border-radius: 3px;
  border: 1px solid transparent;
}

.range::-ms-tooltip { display: none; /* display and visibility only */ }

.range::-webkit-slider-thumb {
  -webkit-appearance: none;
  border-radius: 100%;
  background-color: #6574CF;
  height: 18px;
  width: 18px;
  margin-top: -7px;
}

output {
  min-width: 1em;
  font-family: var(--ff-number);
  font-size: 16px;
  border-radius: 3px;
}


  
  
<!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="CS.css">
    <script src="https://kit.fontawesome.com/79efab5353.js" crossorigin="anonymous"></script>
    <script src="CS.js" defer></script>
    <title>Document</title>
</head>
<body>

    <div>
        <h3 class="info" class="infoExit" id="show" class="show">
            <span style = "">
                
            <i id="exit" class="fas fa-times"></i>
            </span>
            <p id="infohead">Did you know?</p>
        <br>
        <br>
            <b>6.850.000</b> passwords are getting hacked each day? 
            <br>
            <br>
            That is <b>158</b> each second!
        <br>
        <br>
            Stop that from being you. 
        <br>
        <br>
            Let us help you make a strong password.
            <span>
            <i id="nextArrow" class="fas fa-chevron-circle-right"></i>
        </span>
        </h3>
        
    </div>
    
    <div class="container">

        <h2>Password Generator</h2>

        <div class="result-container">
            <span id="result"></span>
            <button class="btn" id="clipboard">
                <section style = "font-size: 0.6em;">
                <i class="far fa-clipboard"></i> 
            </section>
            </button>
        </div>

        <span style = "font-size: 2em; color: rgb(209, 204, 214)">
            <i id="questionClick" class="fas fa-question-circle"></i>
        </span>

        <div class="settings">

            <div class="setting">
                <label>Password length</label>
                <input type="range" class="range" id="length" min='4' max='20' value='20' onmousemove="rangevalue1.value=value" />
                <output id="rangevalue1"></output>
            </div>

            <div class="setting">
                <label>Include uppercase letters</label> 
                <li>
                    <input class="styled-checkbox" id="uppercase" type="checkbox" value="value2" checked>
                    <label for="uppercase"></label>
                  </li>
                
            </div>
            <div class="setting">
                <label>Include lowercase letters</label> 
                <li>
                    <input class="styled-checkbox" id="lowercase" type="checkbox" value="value2" checked>
                    <label for="lowercase"></label>
                  </li>
            </div>

            <div class="setting">
                <label>Include numbers</label> 
                <li>
                    <input class="styled-checkbox" id="numbers" type="checkbox" value="value2" checked>
                    <label for="numbers"></label>
                  </li>
            </div>

            <div class="setting">
                <label for="styled-checkbox-2">Include symbols</label> 
                <li>
                    <input class="styled-checkbox" id="symbols" type="checkbox" value="value2" checked>
                    <label for="symbols"></label>
                  </li>
            </div>

        </div>

        

        <button class="btn btn-large" id="generate">
            Generate password
        </button>

        
            <h3 id="showSecond">
                <span style = "">
                    
                <i id="exitOpt" class="fas fa-times"></i>
                </span>
                <p id="infohead">What is a safe password?</p>
            <br>
            <br>
                <b>7 characters</b> is normally the <b>minimum</b> length of a password with mixed symbols. <br><br>But it is highly recomended to use much more.
                <br>
                <br>
                <b>The best possible password contains of 12 or more characters, mixed with symbols, numbers. lower & uppercase characters.</b>
                
                <span>
                <i id="nextArrowOpt" class="fas fa-chevron-circle-right"></i>
            </span>
            </h3>



            
        
            
        
          

    </div>

   
   
    
    
    
        
   
    
    
   

</body>
</html>


Solution

  • Try using these function as below. Have updated the bare minimum.

    press.addEventListener("click", function () {
    
        show.classList.add("info");
        show.classList.remove("infoExit");
        arrow.style.opacity = "0"
        exit.style.opacity = "0"
        
        setTimeout(function() {
            exit.style.opacity = "100"
        }, (400));
        setTimeout(function() {
            arrow.style.opacity = "100"
        }, (1300));
    
    }); 
    
    hide.addEventListener("click", function () {
    setTimeout(function() {
        show.classList.remove("info");
        },1600);
    
        showOpt.style.width = "0em"
        hide.style.opacity = "40%"
       show.classList.add("infoExit");
    setTimeout(function() {
            arrow.style.opacity = "0"
        }, (00));
    setTimeout(function() {
            exit.style.opacity = "0"
        }, (800));
        
    });