skip to Main Content

Run below code snippet, you will notice the on fadeOut complete I have fadeIn the relative div. The div is blinking other than first I have tried to change the timings or ‘fast’, ‘slow’ the transitions also. Not worked for me.

Please provide best fit to do this kind in minimal code logic.

$(document).on("click", ".action a", function (event) {
    let dataSlide = $(this).attr("data-slide");
    $(".slider .slide .slides").fadeOut(0, function () {
        $(".data-slide-" + dataSlide).fadeIn();
    });
});
.slides {
    display: none;
}
.data-slide-1{
    display: block;
}
a{
  background:#ccc;
  padding:4px 6px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="action">
    <a data-slide="1">1</a>
    <a data-slide="2">2</a>
    <a data-slide="3">3</a>
</div>
<div class="slider">
    <div class="slide">
        <div class="slides data-slide-1">
            <h1>Slide 1</h1>
        </div>
        <div class="slides data-slide-2">
            <h1>Slide 2</h1>
        </div>
        <div class="slides data-slide-3">
            <h1>Slide 3</h1>
        </div>
    </div>
</div>

3

Answers


  1. Edit: The issue is that it’s per element not just the visible one, and the non-visible ones complete immediately.

    Use siblings() to make sure only one animation on one element at same time.

    $(document).on("click", ".action a", function(event) {
      let slide = $(".data-slide-" + $(this).attr("data-slide"))
      slide.siblings().fadeOut(0, function() {
        slide.fadeIn();
      });
    });
    .slides {
      display: none;
    }
    
    .data-slide-1 {
      display: block;
    }
    
    a {
      background: #ccc;
      padding: 4px 6px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="action">
      <a data-slide="1">1</a>
      <a data-slide="2">2</a>
      <a data-slide="3">3</a>
    </div>
    <div class="slider">
      <div class="slide">
        <div class="slides data-slide-1">
          <h1>Slide 1</h1>
        </div>
        <div class="slides data-slide-2">
          <h1>Slide 2</h1>
        </div>
        <div class="slides data-slide-3">
          <h1>Slide 3</h1>
        </div>
      </div>
    </div>
    Login or Signup to reply.
  2. You can use .promise() i.e once the fadeout finishes you call fadein, The .promise() method returns a dynamically generated Promise that is resolved once all actions in previous chain are ended.

    $(document).ready(function () {
      $(document).on("click", ".action a", function (event) {
        let slide = $(".data-slide-" + $(this).attr("data-slide"));
        slide.siblings().fadeOut(0).promise().done(function () {
          slide.fadeIn();
        });
      });
    });
    

    here’s the fiddle:
    https://codepen.io/nitinjs-the-typescripter/pen/XWxbOyW

    Login or Signup to reply.
  3. The issue is described here:

    http://api.jquery.com/fadeout/

    complete
    A function to call once the animation is complete, called once per matched element.

    Because your .fadeOut is called on all 3 elements, each gets its own callback and because only 1 is visible, the others area already hidden so the .fadeIn is called immediately (hence appearing to run at the same time) twice and then a third time for the visible element.

    You can confirm this by adding a console.log inside the callback:

    $(".slider .slide .slides").fadeOut(0, function () {
        $(".data-slide-" + dataSlide).fadeIn();
        console.log($(this).text())
    });
    

    My solution would be to track the "active" element, only hide that and then you only get one callback.

    $(document).on("click", ".action a", function(event) {
      let dataSlide = $(this).attr("data-slide");
      $(".slide.active")
        .removeClass("active")
        .fadeOut(500, function() {
          $(".data-slide-" + dataSlide)
            .addClass("active")
            .fadeIn(500);
        })
    });
    $(".slide.data-slide-1").addClass("active").show();
    .slide {
      display: none;
    }
    
    a {
      background: #ccc;
      padding: 4px 6px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="action">
      <a data-slide="1">1</a>
      <a data-slide="2">2</a>
      <a data-slide="3">3</a>
    </div>
    <div class="slider">
      <div class="slides">
        <div class="slide data-slide-1">
          <h1>Slide 1</h1>
        </div>
        <div class="slide data-slide-2">
          <h1>Slide 2</h1>
        </div>
        <div class="slide data-slide-3">
          <h1>Slide 3</h1>
        </div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search