代码之家  ›  专栏  ›  技术社区  ›  Anakin

如何使用纯JavaScript实现fadeOut效果

  •  67
  • Anakin  · 技术社区  · 10 年前

    我正在尝试为 div 具有 纯JavaScript .

    这是我目前正在使用的:

    //Imagine I want to fadeOut an element with id = "target"
    function fadeOutEffect()
    {
     var fadeTarget = document.getElementById("target");
     var fadeEffect = setInterval(function() {
      if (fadeTarget.style.opacity < 0.1)
      {
       clearInterval(fadeEffect);
      }
      else
      {
       fadeTarget.style.opacity -= 0.1;
      }
     }, 200);
    }
    

    div应该会平滑淡出,但它会立即消失。

    发生了什么?我该怎么解决?

    jsbin

    7 回复  |  直到 3 年前
        1
  •  114
  •   Ruan Mendes    5 年前

    最初,当没有设置不透明度时,值将是一个空字符串,这将导致运算失败。即, "" < 0.1 == true 然后你的代码进入 clearInterval 树枝

    您可以将其默认为1,它将工作。

    function fadeOutEffect() {
        var fadeTarget = document.getElementById("target");
        var fadeEffect = setInterval(function () {
            if (!fadeTarget.style.opacity) {
                fadeTarget.style.opacity = 1;
            }
            if (fadeTarget.style.opacity > 0) {
                fadeTarget.style.opacity -= 0.1;
            } else {
                clearInterval(fadeEffect);
            }
        }, 200);
    }
    
    document.getElementById("target").addEventListener('click', fadeOutEffect);
    #target {
        height: 100px;
        background-color: red;
    }
    <div id="target">Click to fade</div>

    在进行算术和比较时,JavaScript似乎将空字符串视为0(即使在CSS中,它将空字符串作为完全不透明)

    > '' < 0.1
    > true
    
    > '' > 0.1
    > false
    
    
    > '' - 0.1
    > -0.1
    

    更简单的方法 我们现在可以使用 CSS transitions 用更少的代码实现淡出

    const target = document.getElementById("target");
    
    target.addEventListener('click', () => target.style.opacity = '0');
    // If you want to remove it from the page after the fadeout
    target.addEventListener('transitionend', () => target.remove());
    #target {
        height: 100px;
        background-color: red;
        transition: opacity 1s;
    }
    <p>Some text before<p>
    <div id="target">Click to fade</div>
    <p>Some text after</p>
        2
  •  32
  •   Lucas Ferreira    10 年前

    就在今天早上,我在 http://vanilla-js.com ,它非常简单、紧凑和快速:

    var s = document.getElementById('thing').style;
    s.opacity = 1;
    (function fade(){(s.opacity-=.1)<0?s.display="none":setTimeout(fade,40)})();
    

    您可以更改渐变的速度,更改 setTimeOut 作用

    var s = document.getElementById('thing').style;
    s.opacity = 1;
    (function fade(){(s.opacity-=.1)<0?s.display="none":setTimeout(fade,40)})();
    #thing {
      background: red;
      line-height: 40px;
    }
    <div id="thing">I will fade...</div>
        3
  •  18
  •   Alexander Tarasenko    5 年前

    看起来你可以用另一种方式(我可能错了)。

    event.target.style.transition = '0.8s';
    event.target.style.opacity = 0;
    
        4
  •  7
  •   Vikash    10 年前

    您可以使用CSS转换属性,而不是在javascript中使用vai-timer。与你所做的相比,这更注重绩效。

    检查

    http://fvsch.com/code/transition-fade/test5.html#test3

        5
  •  5
  •   Alex Nolasco    4 年前

    除了公认的答案,我们现在还有 WAAPI 这基本上为JavaScript添加了动画API。

    例如

    /**
     * @returns {Object}
    */
    function defaultFadeConfig() {
      return {      
          easing: 'linear', 
          iterations: 1, 
          direction: 'normal', 
          fill: 'forwards',
          delay: 0,
          endDelay: 0
        }  
    }
    
    /** 
     * @param {HTMLElement} el
     * @param {number} durationInMs
     * @param {Object} config
     * @returns {Promise}
     */
    async function fadeOut(el, durationInMs, config = defaultFadeConfig()) {  
      return new Promise((resolve, reject) => {         
        const animation = el.animate([
          { opacity: '1' },
          { opacity: '0', offset: 0.5 },
          { opacity: '0', offset: 1 }
        ], {duration: durationInMs, ...config});
        animation.onfinish = () => resolve();
      })
    }
    
    /** 
     * @param {HTMLElement} el
     * @param {number} durationInMs
     * @param {Object} config
     * @returns {Promise}
     */
    async function fadeIn(el, durationInMs, config = defaultFadeConfig()) {
      return new Promise((resolve) => {         
        const animation = el.animate([
          { opacity: '0' },
          { opacity: '0.5', offset: 0.5 },
          { opacity: '1', offset: 1 }
        ], {duration: durationInMs, ...config});
        animation.onfinish = () => resolve();
      });
    }
    
    window.addEventListener('load', async ()=> {
      const el = document.getElementById('el1');  
      for(const ipsum of "Neque porro quisquam est qui dolorem ipsum quia dolor \uD83D\uDE00".split(' ')) {
        await fadeOut(el, 1000);  
        el.innerText = ipsum;
        await fadeIn(el, 2000);
      }
    });
    .text-center {
      text-align: center;
    }
    <h1 id="el1" class="text-center">...</h1>
        6
  •  3
  •   mahdiros    4 年前

    function fadeOutEffect() {
        var fadeTarget = document.getElementById("target");
        var fadeEffect = setInterval(function () {
            if (!fadeTarget.style.opacity) {
                fadeTarget.style.opacity = 1;
            }
            if (fadeTarget.style.opacity > 0) {
                fadeTarget.style.opacity -= 0.1;
            } else {
                clearInterval(fadeEffect);
            }
        }, 200);
    }
    
    document.getElementById("target").addEventListener('click', fadeOutEffect);
    #target {
        height: 100px;
        background-color: red;
    }
    <div id="target">Click to fade</div>
        7
  •  0
  •   Lex Jad    3 年前

    我的解决方案

    function fadeOut(selector, timeInterval, callback = null) {
    
        var fadeTarget = document.querySelector(selector);
    
        let time = timeInterval / 1000;
        fadeTarget.style.transition = time + 's';
        fadeTarget.style.opacity = 0;
        var fadeEffect = setInterval(function() {
    
            if (fadeTarget.style.opacity <= 0)
            {
                clearInterval(fadeEffect);
                if (typeof (callback) === 'function') {
                    callback();
                }
            }
        }, timeInterval);
    }