I'm experiencing an unwanted visual effect when changing tabs. What I want is for .policyCentre__content sections to fade out slowly, and to fade in the relevant section slowly too. However, when you change tab initially, if it's the first time the matching policyCentre__content is loaded, it will blink in, rather than fade.
See steps to reproduce:
- Run the below demo (you will start off with "tab 1" active.
- Click "tab 2" and watch the content appear ("tab 1" content fades out, but content for "tab 2" just appears.
- Click back onto "tab 1", and the content disappears and appears as intended.
- Click back onto "tab 2" and it now works as intended.
Unsure why the 2nd step initially just makes the content appear?
$(function() {
function showContent(val){
$(".policyCentre__content.active").fadeOut(500, function() {
$(this).removeClass("active");
$(window).scrollTop(0);
$(".policyCentre__content[data-item='" val "']").addClass('active').fadeIn(500, function() {
locked = false;
})
});
}
// prevent the UI from getting over-clicked
let locked = false;
$(".policyCentre__label:first, .policyCentre__content:first").addClass("active");
$('.policyCentre__label').click(function() {
if (locked) return;
locked = true;
var id = $(this).attr('data-item');
$(".policyCentre__label").removeClass("active");
$(this).addClass("active");
showContent(id);
});
});
.policyCentre {
border: 1px solid black;
padding: 60px 0;
}
.policyCentre__label {
display: inline-block;
cursor: pointer;
position: relative;
margin-bottom: 10px;
width: fit-content;
display: flex;
align-items: center;
}
.policyCentre__label:hover, .policyCentre__label.active {
color: orange;
}
.policyCentre__content {
display: none;
padding-left: 50px;
}
.policyCentre__content.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<section >
<div >
<div >
<div >
<div >
<span data-item="tab-1">Tab 1</span>
<span data-item="tab-2">Tab 2</span>
<span data-item="tab-3">Tab 3</span>
</div>
</div>
<div >
<div data-item="tab-1">Copy for tab 1</div>
<div data-item="tab-2">Copy for tab 2</div>
<div data-item="tab-3">Copy for tab 3</div>
</div>
</div>
</div>
</section>
CodePudding user response:
I believe it's because you have this rule in your CSS:
.policyCentre__content.active {
display:block;
}
...which is forcing the div to show immmediately (rather than animate in) when you apply the 'active' class. I removed that rule and instead used your hide/show function to show the first tab (rather than relying on that display:block css rule). Because (for this first transition) we aren't hiding anything, I broke your hide/show function into 2 (transitionContent() and showContent()) so we could just call showContent() initially.
$(function() {
function transitionContent(val) {
$(".policyCentre__content.active").fadeOut(500, function() {
$(this).removeClass("active");
$(window).scrollTop(0);
showContent(val)
});
}
function showContent(val) {
$(".policyCentre__content[data-item='" val "']").addClass('active').fadeIn(500, function() {
locked = false;
})
}
showContent('tab-1')
// prevent the UI from getting over-clicked
let locked = false;
$(".policyCentre__label:first, .policyCentre__content:first").addClass("active");
$('.policyCentre__label').click(function() {
if (locked) return;
locked = true;
var id = $(this).attr('data-item');
$(".policyCentre__label").removeClass("active");
$(this).addClass("active");
transitionContent(id);
});
});
.policyCentre {
border: 1px solid black;
padding: 60px 0;
}
.policyCentre__label {
display: inline-block;
cursor: pointer;
position: relative;
margin-bottom: 10px;
width: fit-content;
display: flex;
align-items: center;
}
.policyCentre__label:hover,
.policyCentre__label.active {
color: orange;
}
.policyCentre__content {
display: none;
padding-left: 50px;
}
.policyCentre__content.active {}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<section >
<div >
<div >
<div >
<div >
<span data-item="tab-1">Tab 1</span>
<span data-item="tab-2">Tab 2</span>
<span data-item="tab-3">Tab 3</span>
</div>
</div>
<div >
<div data-item="tab-1">Copy for tab 1</div>
<div data-item="tab-2">Copy for tab 2</div>
<div data-item="tab-3">Copy for tab 3</div>
</div>
</div>
</div>
</section>
