Search code examples
javascriptanimationdomfadeinfadeout

Plain DOM fadeOut then fadeIn immediately


I would like to implement fadeIn and fadeOut using the native DOM, without JQuery.

If we click the button twice fast, means it will start to fadeOut when fadeIn is still ongoing, the text will be flickering.

Here's the codes in jsfiddle: https://jsfiddle.net/keegoo/vyuqdxLs/

Any ideas on how to fix that?

document.getElementById('button').addEventListener('click', () => switch_state())
const text = document.getElementById('text')
const btn = document.getElementById('button')
let state = true

function switch_state() {
  if (state == true) {
    fadeOut(text, 3000)
    btn.innerHTML = 'show'
    state = false
  } else {
    fadeIn(text, 3000)
    state = true
    btn.innerHTML = 'hide'
  }
}

function fadeOut(elem, ms) {
  elem.style.opacity = 1
  if (ms) {
    let opacity = 1
    const timer = setInterval(() => {
      opacity -= 50 / ms
      if (opacity <= 0) {
        clearInterval(timer)
        opacity = 0
      }
      elem.style.opacity = opacity
    }, 50)
  } else {
    elem.style.opacity = 0
  }
}

function fadeIn(elem, ms) {
  elem.style.opacity = 0;

  if (ms) {
    let opacity = 0;
    const timer = setInterval(function() {
      opacity += 50 / ms;
      if (opacity >= 1) {
        clearInterval(timer);
        opacity = 1;
      }
      elem.style.opacity = opacity;
    }, 50);
  } else {
    elem.style.opacity = 1;
  }
}
<button id='button'>hide</button>
<text id='text'>some text</text>


Solution

  • You could do it like this with setProperty.

    document.getElementById('button').addEventListener('click', () => switch_state())
    const text = document.getElementById('text')
    const btn = document.getElementById('button')
    let state = true
    
    function switch_state() {
      if (state == true) {
        fadeOut(text, 800)
        btn.innerHTML = 'show'
        state = false
      } else {
        fadeIn(text, 800)
        state = true
        btn.innerHTML = 'hide'
      }
    }
    
    function fadeOut(elem, ms) {
      elem.style.setProperty("opacity",0);
      elem.style.setProperty("transition", "opacity " + ms + "ms");
    }
    
    function fadeIn(elem, ms) {
      elem.style.setProperty("opacity",1);
      elem.style.setProperty("transition", "opacity " + ms + "ms");
    }
    <button id='button'>hide</button>
    <text id='text'>some text</text>