Анимация кнопок неверна только при первом запуске после обновления браузера

#javascript #html #css #css-transitions #css-transforms

Вопрос:

Моя цель-создать кнопку меню, которая переходит от 3 горизонтальных линий к «X».

Мне удалось добиться этого, но небольшая проблема, с которой я сталкиваюсь, заключается в том, что анимация совершенна только ПОСЛЕ первого щелчка. Если я обновлю браузер и нажму кнопку, он не будет работать правильно.

Трудно заметить, если я оставлю анимацию на 0,1 секунды, как я намеревался, поэтому я замедлил ее до 1 секунды.

Вот весь соответствующий код, вы можете просто скопировать и вставить его, чтобы проверить. Имейте в виду, что это идеально создано для iPhone 6/7/8 Plus с использованием браузера.

 const menuButton = document.querySelector('.menu-button')
const menuButtonLines = document.querySelectorAll('.line')

let menuIsOpen = false;

// functions for MenuButton

let changeOpacity = x => {
  if (menuIsOpen === false) {
    menuButtonLines[x].style.transition = 'opacity 1s linear'
    menuButtonLines[x].style.opacity = '0%'
  } else if (menuIsOpen === true) {
    menuButtonLines[x].style.transition = 'opacity 1s linear'
    menuButtonLines[x].style.opacity = '100%'
  }
}

let rotateAndAdjustMenuButtonXLines = (x, y) => {
  if (menuIsOpen === false) {
    menuButtonLines[x].style.transition = 'all 1s linear'
    menuButtonLines[y].style.transition = 'all 1s linear'
    menuButtonLines[x].style.transform = 'rotate(45deg)'
    menuButtonLines[y].style.transform = 'rotate(-45deg)'
    menuButtonLines[x].style.top = '42.5%'
    menuButtonLines[y].style.bottom = '42.5%'
  } else if (menuIsOpen === true) {
    menuButtonLines[x].style.transition = 'all 1s linear'
    menuButtonLines[y].style.transition = 'all 1s linear'
    menuButtonLines[x].style.transform = 'rotate(0deg)'
    menuButtonLines[y].style.transform = 'rotate(0deg)'
    menuButtonLines[x].style.top = '0%'
    menuButtonLines[y].style.bottom = '0%'
  }
} 
 * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
    font-family: 'Inter', sans-serif;
}

/* button styling removal code */

button {
    background: transparent;
    box-shadow: 0px 0px 0px transparent;
    border: 0px solid transparent;
    text-shadow: 0px 0px 0px transparent;
}

button:hover {
    background: transparent;
    box-shadow: 0px 0px 0px transparent;
    text-shadow: 0px 0px 0px transparent;
}

button:active {
    outline: none;
    border: none;
}

button:focus {
    outline: 0;
}

/* ---------------------------------------- */

body {
    height: 100%;
    width: 100%;
}

.logo-and-menu-buttom {
    background-color: white;
    height: 17.5vh;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-evenly;
}

.menu-button {
    border: 0.3vh solid black;
    border-radius: 0.25vh;
    width: 20%;
    height: 30%;
    display: flex;
    align-items: center;
    justify-content: space-evenly;
}

.line-container {
    height: 40%;
    width: 20%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
}

.line {
    position: relative;
    border: 0.1vh solid black;
    border-radius: 100vh;
    width: 100%;
}

.menu-button p {
    font-weight: bold;
    letter-spacing: 0.1vh;
} 
 <section class="logo-and-menu-buttom">
  <button class="menu-button">
                <div class="line-container">
                    <div class="line"></div>
                    <div class="line"></div>
                    <div class="line"></div>
                </div>
                <p>Menu</p>
            </button>
</section> 

Ответ №1:

Проблема в том, что ваша «правильная» анимация основана на стилях, которые вы даете своим элементам с помощью js, а не html и css, поэтому они не существуют до запуска js, поэтому в первый раз это выглядит по-другому.

Чтобы решить вашу проблему, все, что вам нужно сделать, это добавить эти стили, поэтому измените свой html с :

 <div class="line-container">
  <div class="line"></div>
  <div class="line"></div>
  <div class="line"></div>
</div>
 

Для:

 <div class="line-container">
  <div class="line" style="top: 0"></div>
  <div class="line"></div>
  <div class="line" style="bottom: 0"></div>
</div>
 

Даже несмотря на то, что я настоятельно рекомендую переключиться с анимации на основе js на анимацию на основе css с синтаксисом css-анимации и 2 различными классами с различными анимациями закрытия и открытия.