Search code examples
javascripthtmlcssfade

Fading in and out text in block


I have a block which content is being dynamically changed by script and I want that content not to change instantly, but fade out and then fade in with new content. I want that done without jQuery — pure JS and CSS. I am trying to do this in such a way: I've defined transparent and opacle classes in CSS with transition set to 2s, and wanna toggle that classes for block with content when the content changes. As I expect it should smoothly fade out old content and fade in new content. But in fact content just changes instantly. CSS:

.non-opacle {
    opacity:0;
    transition: opacity 2s linear;
}
.opacle {
    opacity:1;
    transition: opacity 2s linear;
}

HTML

       <div class="alert alert-info" id="wrapper">
            <p id="text-box">…</p>
        </div>

JS

var textBox = document.getElementById('text-box');
window.onload = function () {
    var failCounter = 0;
    var current = notes[Math.floor(Math.random() * 12)];
    textBox.className = 'opacle';
    textBox.innerHTML = '…';
    function keyClicked(event) {
        if (event.target.className.split(' ')[1] === current) {
            textBox.className = 'non-opacle';
            textBox.innerHTML = '*some altered content*';
            textBox.className = 'opacle';
    …

In JS I initially set content wrapper block to 'opacle' class with initial content, and then on certain conditions, I set it to 'non-opacle', change block's innerHTML to place relevant content, and set the class back to 'opacle'. But no animation occurs( What am I doing wrong?


Solution

  • Your problem is that you're adding and removing the opacity at the same time, before the initial transition has had time to complete.

    What you need to do is delay the changing of the innerHTML and resetting of the opacity until the transition has completed.

    Here's a very simple looping example to illustrate the principle, the important part to note is the setTimeout.

    var p=document.getElementById("change"),text=["One","Two","Three","Four","Five"],x=0,interval=setInterval(function(){
        x++;if(x===text.length)x=0;
        p.classList.add("hide");
        setTimeout(function(){
            p.innerHTML=text[x];
            p.classList.remove("hide");
        },500);
    },2000);
    #change{
        color:#000;
        font-family:arial;
        padding:5px;
        transition:opacity .5s linear;
    }
    .hide{
        opacity:0;
    }
    <p id="change">One</p>