2

I'm having trouble with the following situation.

I have a button which acts like a normal toggle. When I click on the "Animate" button, I want the <p>This is new Div</p> to fade in when I again click on the Animate button, this <p> should fade out.

How can I achieve this?

const main = document.getElementById('main');
const btn = document.getElementById('btn');

let show = false;
btn.addEventListener('click', () => {
  if(show) {
    const newDiv = document.getElementById("new-div");
    newDiv.remove();
    show = false;
  } else {
    const newDiv = document.createElement('div');
    newDiv.id = "new-div";
    newDiv.innerHTML = "<p>This is new Div</p>";
    main.appendChild(newDiv);
    show = true;
  }
})
#new-div {
  transition: all 2s ease-in-out;
}
<div id="main">
  <button id="btn">Animate</button>
</div>

I'm actually building a gallary layout app, which requires to fade in when clicked on a image + show in full screen, then fade out to its original position when clicked. Since there will be many images, I want to use JS to dynamically work on this.

And the biggest hurdle so far is to implement fade-out, because the element is being deleted.

MARSHMALLOW
  • 1,315
  • 2
  • 12
  • 24
cdadityang
  • 523
  • 2
  • 10
  • where is your animation? – Omri Attiya Apr 15 '20 at 14:00
  • Does this answer your question? [CSS transition fade in](https://stackoverflow.com/questions/11660710/css-transition-fade-in) – Omri Attiya Apr 15 '20 at 14:11
  • @OmriAttiya, I couldn't think of any proper animation, so didn't include it. And no the above mentioned question doesn't answer my question, I'm looking for both `fade in` and `fade out` implementation – cdadityang Apr 15 '20 at 18:51
  • It's the same since you use it for all transitions. Read more about transitions and how they work – Omri Attiya Apr 15 '20 at 18:54
  • I've found a potential solution for this problem: https://jsfiddle.net/0g5cbun6/ But what is the support of `animationend` event listener for browsers? I'm not understanding what https://caniuse.com says – cdadityang Apr 15 '20 at 19:17
  • WebKit has another event for this, pls check out https://jsfiddle.net/Kenvdb/8nsbp16o/ – KennyDope Apr 16 '20 at 12:35

4 Answers4

2

Based on your information I've made a refined version, pls see fiddle and code below: https://jsfiddle.net/Kenvdb/8nsbp16o/

JavaScript:

const main = document.getElementById('main');
const btn = document.getElementById('btn');

let toggledDiv = null;

btn.addEventListener('click', () => {
  if (!toggledDiv) {
    show();
  } else {
    hide();
  }
})

const show = () => {
  toggledDiv = document.createElement('div');
  toggledDiv.id = "content";
  toggledDiv.style.opacity = "1";
  toggledDiv.innerHTML = "<p>This is new Div</p>";

  main.appendChild(toggledDiv);
}

const hide = () => {
  toggledDiv.style.animation = "fade-out 0.5s ease-in";
  toggledDiv.style.opacity = "0";
  toggledDiv.addEventListener('animationend', remove);
  toggledDiv.addEventListener('webkitAnimationEnd', remove);
}

const remove = () => {
  toggledDiv.remove();
  toggledDiv = null;
};

CSS:

#content {
  opacity: 0;
  animation: fade-in 0.5s ease-in;
}

@keyframes fade-in {
    0% { opacity: 0; }
    100% { opacity: 1; }
}

@keyframes fade-out {
    0% { opacity: 1; }
    100% { opacity: 0; }
}

HTML:

<div id="main">
  <button id="btn">Animate</button>
</div>
KennyDope
  • 429
  • 1
  • 4
  • 13
0

You'll need to set the opacity to 0 first. Then you can apply a keyframe animation. Otherwise, the element has nothing to transition from.

See below.

#new-div {
  opacity: 1;
  animation: fadeIn 2s ease-in-out;

}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
}
  • Hey, I got this already. The problem is how do you implement the `fade out` now? Since the element is deleted(see my JS code), the animation seems not to work for fade out. – cdadityang Apr 15 '20 at 18:36
0

There's several ways of doing this. You can set the opacity of the newly added element using the style attribute:

const main = document.getElementById('main');
const btn = document.getElementById('btn');

let show = false;
let fading = false;
btn.addEventListener('click', () => {
  if (fading) return;
  if (show) {
    const newDiv = document.getElementById("new-div");
    newDiv.style = "opacity: 0"; // start the fade
    fading = true;
    window.setTimeout(function() {
      fading = false; // disable showing/hiding while fading
      newDiv.remove(); // remove after fade completed
      show = false;
    }, 2000);
  } else {
    show = true;
    const newDiv = document.createElement('div');
    newDiv.id = "new-div";
    newDiv.innerHTML = "<p>This is new Div</p>";
    main.appendChild(newDiv);
    window.setTimeout(function() {
      newDiv.style = "opacity: 1"; // Start fading after a minimal time
    });
  }
})
#new-div {
  transition: all 2s ease-in-out;
  opacity: 0;
}
<div id="main">
  <button id="btn">Animate</button>
</div>

Or you can use jQuery, which significantly reduce the code:

$("#btn").on('click', () => {
  var newDiv = $("#new-div");
  if (newDiv.length) {
    newDiv.stop().fadeOut(2000, function() {
      newDiv.remove();
    });
  } else {
    $(`<div id='new-div'>
       <p>This is new Div</p>
       </div`).appendTo("#main").hide().fadeIn(2000);
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main">
  <button id="btn">Animate</button>
</div>
ariel
  • 15,620
  • 12
  • 61
  • 73
  • Hi, BTW in your vanilla JS answer, the fade out animation is only working. What I need is both - fade in and fade out. Thanks in advance. – cdadityang Apr 15 '20 at 18:39
  • I'm want to implement this in vanilla JS. – cdadityang Apr 15 '20 at 18:39
  • I've found a potential solution for this problem: https://jsfiddle.net/0g5cbun6 , could you help me with support of `animationend` event listener? – cdadityang Apr 15 '20 at 19:20
-1

You can do it simply using both of fadeIn() and fadeOut() methods in jQuery.

Here is an example:

let alreadyClicked = false;

$("#btn").click(function() {
   if(alreadyClicked == false) {
      $("p").remove(); //Remove the paragraph if already created.
      $("#main").append("<p style='display: none;'>Hello, world!</p>"); //Create a paragraph.
      $("p").fadeIn(); //Show it by fading it in.
      alreadyClicked = true;
   } else {
      $("p").fadeOut();  //Fade it out
      alreadyClicked = false;
   }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main">
  <button id="btn">Animate</button>
</div>
MARSHMALLOW
  • 1,315
  • 2
  • 12
  • 24