Попытка выполнить переходы CSS через JavaScript не сработает

CSS-переходы у меня не работают, когда я пытаюсь выполнить их через JavaScript.

let isSearchBarOpen = false;

function toggleSearchBar() {
  if (isSearchBarOpen) {
    searchBar.style.display = "none";
  } else {
    searchBar.style.display = "flex";
    searchBar.classList.add("search-bar-open")
  }
  isSearchBarOpen = !isSearchBarOpen;

  toggleSearchIcon();
}
.search-bar {
  display: none;
  background-color: #000;
  color: #fff;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  padding: 10px 5px;
  z-index: 1000;
  margin: 0 auto;
  transition: top 2s ease-in;
}

.search-bar-open {
  top: 90px;
}
<div class = "search-icon">
  <i class = "fas fa-search search-icon-header"></i>
  <img src = "images/close-icon.svg" alt = "close-icon-search" class = "close-icon-search">
</div>
<div class = "search-bar" id = "search-bar">
  <div class = "search-container">
    <form class = "search-form">
      <input type = "text" placeholder = "Search...">
      <button type = "submit"><i class = "fas fa-search search-icon-action"></i></button>
    </form>
  </div>
</div>

При нажатии кнопки поиска происходят следующие вещи (или должны произойти, если я не ошибаюсь):

  1. Функция проверяет, является ли isSearchBarOpentrue или false.
  2. Если true — то есть если панель поиска открыта — добавляется встроенный стиль (display:none), скрывающий панель.
  3. Если это false, то есть если панель поиска закрыта, добавляется встроенный стиль (display:flex), чтобы он отображался. И, кроме того, добавлен класс (.search-bar-open).

Отсюда, если мы посмотрим на CSS…

  1. Панель поиска при открытии (когда она появляется) загружает класс .search-bar-open и встроенный стиль display:flex. С одной стороны, указанный встроенный стиль переопределяет свойство CSS display:none, применяемое через класс .search-bar, по своей специфике.

  2. И, кроме того, добавлен класс .search-bar-open.

  3. Теперь я предполагаю, что при применении класса .search-bar-open должен произойти переход, предусмотренный внутри .search-bar, то есть:

а. Я в top:0;

б. И за 2 секунды с легкостью…

в. Я настроен top:90px;.

Я что-то неправильно понял, потому что это не работает :-(

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
50
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Если вы используете JS, чтобы сделать элемент видимым И добавить класс для запуска перехода, это не сработает, потому что JS выполняет оба этих действия одновременно. Переход сработает, если свойство элемента будет изменено, но в этом случае свойство top никогда не изменяется, оно уже было там, когда элемент стал видимым.

Вы можете добавить действие JS между ними, чтобы вызвать перекомпоновку браузера. Таким образом, браузер сначала делает элемент видимым, рисует его на странице, а затем добавляет класс для запуска перехода.

searchBar.style.display = "flex";
searchBar.offsetWidth;
searchBar.classList.add("search-bar-open")

Дорогой Рене, Все получилось отлично. Следуя вашему совету, я даже исправил кое-что еще. Большое спасибо!

Ibai Fernández 27.09.2023 20:13

проблема в том, что переходы не работают для свойств display: none, вместо того, чтобы использовать display none для гибкости, просто сделайте что-нибудь, чтобы скрыть панель поиска, не делая display: none;

одно из возможных решений — задать отрицательное верхнее значение для удаления из видимого окна. например top: -50px (или вы можете указать точное значение, соответствующее высоте панели поиска)

let isSearchBarOpen = false;

    function toggleSearchBar() {
          if (isSearchBarOpen) {
            searchBar.style.top= "-50px";   //here used top instead of display
          } else {
             searchBar.classList.add("search-bar-open")
          }
          isSearchBarOpen = !isSearchBarOpen;
            
          toggleSearchIcon();
      }

.search-bar {
    display: flex;      //here let it to be flex
    background-color: #000;
    color: #fff;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    padding: 10px 5px;
    z-index: 1000; 
    margin: 0 auto;
    transition: top 2s ease-in;
}

.search-bar-open {
    top:90px; 
}

Дорогой Джунаид, я не пробовал ваше решение (честно говоря), как сразу сработал Рене. Однако большое спасибо. Ваше здоровье!

Ibai Fernández 27.09.2023 20:14

Переход не работает для display:none. Итак, вместо перехода используйте анимацию.

пример кода:

CSS:

       .search-bar {
            display: none;
            background-color: #000;
            color: #fff;
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            padding: 10px 5px;
            z-index: 1000;
            margin: 0 auto;
            animation: toggleOnAnimation 2s ease-in;
        }

        .search-bar-open {
            top: 90px;
        }

        @keyframes toggleOnAnimation {
            0% {
                top: 0
            }

            100% {
                top: 90px
            }
        }

Javascript:

        let isSearchBarOpen = false;
        let searchBar = document.getElementById("search-bar");
        function toggleSearchBar() {
            if (isSearchBarOpen) {
                searchBar.style.display = "none";
            } else {
                searchBar.style.display = "flex";
                searchBar.classList.add("search-bar-open")
            }
            isSearchBarOpen = !isSearchBarOpen;

        }

HTML:

    <div class = "search-icon">
        <i class = "fas fa-search search-icon-header"></i>
        <!-- <img src = "images/close-icon.svg" alt = "close-icon-search" class = "close-icon-search"> -->
        <button onclick = "toggleSearchBar()">Click</button>
    </div>
    <div class = "search-bar" id = "search-bar">
        <div class = "search-container">
            <form class = "search-form">
                <input type = "text" placeholder = "Search...">
                <button type = "submit">
                    Submit
                </button>
            </form>
        </div>
    </div>

Здесь я использовал анимацию вместо перехода. Надеюсь, вы поняли :)

Дорогой Свалих, я не пробовал ваше решение (честно говоря), как сразу сработал Рене. Однако большое спасибо. Ваше здоровье!

Ibai Fernández 27.09.2023 20:15

Другие вопросы по теме