Как организовать fadeOut() и fadeIn() без моргания?

Рейтинг: 1Ответов: 1Опубликовано: 13.08.2025

Всем привет. Делаю фильтр на страницу. Сделал. Работает. Не нравится анимация. Подскажите, как можно сделать изменение видимости объектов без "моргания"?

Описание проблемы: например если у меня есть 3 объекта , один с фильтром "f1", другой с фильтром "f1,f2", третий с фильтром "f2". Я выбираю селектом фильтр "f2", скрываются все и появляется блоки (2,3). Если после этого я выбираю фильтр "Все", то блок 1 появляется, в два других моргают.

Что я сделал:

$('#filter_select').on('change', function () {
  let val_filter = $(this).val();
  if(val_filter==0){
      $('.box').fadeIn();
  }else{
    $('.box').fadeOut(function(){
      $('.box').each(function(index, val){
        if($(val).data('filtertag').indexOf(val_filter)>=0){
          $(this).fadeIn();
        }
      })
    })
  }
})

UPD. Ну вот пример, просили в комментариях.

$('#filter_select').on('change', function () {
  let val_filter = $(this).val();
  if(val_filter==0){
      $('.box').fadeIn();
  }else{
    $('.box').fadeOut(function(){
      $('.box').each(function(index, val){
        if($(val).data('filtertag').indexOf(val_filter)>=0){
          $(this).fadeIn();
        }
      })
    })
  }
})
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<div class="container">
<select class="form-select my-3" id="filter_select">
  <option value="0" selected>Все фильтры</option>
  <option value="f1">F1</option>
  <option value="f2">F2</option>
  <option value="f3">F3</option>
</select>
<div class="row">
  <div class="col-lg-2 box" data-filtertag="f1,f2">
    <div class="card">
      <img src="https://jjji.ru/300x300" class="card-img-top">
      <div class="card-body">
        <h5 class="card-title">Card title F1-F2</h5>
        <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
        <a href="#" class="btn btn-primary">Go somewhere</a>
      </div>
    </div>
  </div>
  
  <div class="col-lg-2 box" data-filtertag="f3">
    <div class="card">
      <img src="https://jjji.ru/300x300" class="card-img-top">
      <div class="card-body">
        <h5 class="card-title">Card title F3</h5>
        <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
        <a href="#" class="btn btn-primary">Go somewhere</a>
      </div>
    </div>
  </div>
  
  <div class="col-lg-2 box" data-filtertag="f1">
    <div class="card">
      <img src="https://jjji.ru/300x300" class="card-img-top">
      <div class="card-body">
        <h5 class="card-title">Card title F1</h5>
        <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
        <a href="#" class="btn btn-primary">Go somewhere</a>
      </div>
    </div>
  </div>
  
  <div class="col-lg-2 box" data-filtertag="f2">
    <div class="card">
      <img src="https://jjji.ru/300x300" class="card-img-top">
      <div class="card-body">
        <h5 class="card-title">Card title F2</h5>
        <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
        <a href="#" class="btn btn-primary">Go somewhere</a>
      </div>
    </div>
  </div>
</div>
</div>

Ответы

▲ 1Принят

fadeIn и fadeOut показывают элемент с изменением прозрачности, поэтому скачки неизбежны:

$('#filter_select').on('change', function (e) {
  let val_filter = $(e.target).val();

  $('li').each(function () {
    if ($(this).data('filtertag').indexOf(val_filter) >= 0){
      $(this).fadeIn();
    } else {
      $(this).fadeOut();
    }
  })
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<p id="filter_select">
  <label><input type="radio" name="f" value="">(all)</label>
  <label><input type="radio" name="f" value="a">A</label>
  <label><input type="radio" name="f" value="b">B</label>
</p>

<ul>
  <li data-filtertag="a">Only A</li>
  <li data-filtertag="a b">Both</li>
  <li data-filtertag="b">Only B</li>
  <li data-filtertag="a">Only A</li>
  <li data-filtertag="a b">Both</li>
  <li data-filtertag="b">Only B</li>
  <li data-filtertag="a">Only A</li>
  <li data-filtertag="a b">Both</li>
  <li data-filtertag="b">Only B</li>
</ul>

Чтобы было плавно, надо менять не прозрачность, а высоту:

$('#filter_select').on('change', function (e) {
  let val_filter = $(e.target).val();

  $('li').each(function () {
    if ($(this).data('filtertag').indexOf(val_filter) >= 0){
      $(this).show(400);
    } else {
      $(this).hide(400);
    }
  })
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<p id="filter_select">
  <label><input type="radio" name="f" value="">(all)</label>
  <label><input type="radio" name="f" value="a">A</label>
  <label><input type="radio" name="f" value="b">B</label>
</p>

<ul>
  <li data-filtertag="a">Only A</li>
  <li data-filtertag="a b">Both</li>
  <li data-filtertag="b">Only B</li>
  <li data-filtertag="a">Only A</li>
  <li data-filtertag="a b">Both</li>
  <li data-filtertag="b">Only B</li>
  <li data-filtertag="a">Only A</li>
  <li data-filtertag="a b">Both</li>
  <li data-filtertag="b">Only B</li>
</ul>

В принципе, можно совместить и с fade'ом, но на мой взгляд всё меняется слишком быстро, чтобы заметить порзрачность:

$('#filter_select').on('change', function (e) {
  let val_filter = $(e.target).val();

  $('li').each(function () {
    if ($(this).data('filtertag').indexOf(val_filter) >= 0){
      $(this).show(400).fadeIn();
    } else {
      $(this).hide(400).fadeOut();
    }
  })
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<p id="filter_select">
  <label><input type="radio" name="f" value="">(all)</label>
  <label><input type="radio" name="f" value="a">A</label>
  <label><input type="radio" name="f" value="b">B</label>
</p>

<ul>
  <li data-filtertag="a">Only A</li>
  <li data-filtertag="a b">Both</li>
  <li data-filtertag="b">Only B</li>
  <li data-filtertag="a">Only A</li>
  <li data-filtertag="a b">Both</li>
  <li data-filtertag="b">Only B</li>
  <li data-filtertag="a">Only A</li>
  <li data-filtertag="a b">Both</li>
  <li data-filtertag="b">Only B</li>
</ul>