Как организовать fadeOut() и fadeIn() без моргания?
Всем привет. Делаю фильтр на страницу. Сделал. Работает. Не нравится анимация. Подскажите, как можно сделать изменение видимости объектов без "моргания"?
Описание проблемы: например если у меня есть 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/[email protected]/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>