Home > database >  Fade effect blinks first time it's triggered, but then works as intended
Fade effect blinks first time it's triggered, but then works as intended

Time:01-10

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:

  1. Run the below demo (you will start off with "tab 1" active.
  2. Click "tab 2" and watch the content appear ("tab 1" content fades out, but content for "tab 2" just appears.
  3. Click back onto "tab 1", and the content disappears and appears as intended.
  4. 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>

  •  Tags:  
  • Related