【问题标题】:Change of opacity using css transition and vanilla JavaScript works only when fading out使用 css 过渡和 vanilla JavaScript 更改不透明度仅在淡出时有效
【发布时间】:2017-03-20 03:06:41
【问题描述】:

这个 codepen 显示了我的问题:http://codepen.io/PiotrBerebecki/pen/pNvpdG

当用户点击大按钮时,css opacity 减少为 0。由于我应用了以下规则:transition: opacity 0.5s ease-in-out;,淡出动画是平滑的。

我想在下一个按钮淡入时实现同样的平滑过渡。 但是由于某种原因,下一个按钮突然出现,没有任何过渡。

您知道导致问题的原因以及如何解决它吗?

console.clear();

(function() {
  
  // Data for the app
  const model = {
    buttons: ['tomato', 'blue'],
    currentButton: -1
  };
  
  // Logic for the app
  const controller = {
    init: function() {
      view.init();
    },
    getButtonName: function() {
      model.currentButton = (model.currentButton + 1) % model.buttons.length;
      return model.buttons[model.currentButton];
    }
  };
  
  // View for the app
  const view = {
    init: function() {
      this.root = document.getElementById('root');
      this.showNext();
    },
    
    animationDelay: 500,
    
    showNext: function() {
      // Get next button name
      const buttonName = controller.getButtonName();
      
      // Create button DOM element
      const buttonElement = document.createElement('div');
      buttonElement.className = 'button';
      buttonElement.id = buttonName;
      buttonElement.textContent = buttonName;
      buttonElement.style.opacity = 0;
      
      // Add event listender for the button
      buttonElement.addEventListener('click', event => {
        // Reduce opacity
        buttonElement.style.opacity = 0;
        // Remove the button from DOM
        setTimeout(() => {
          this.root.removeChild(buttonElement);
        }, this.animationDelay + 10);
        // Start the function to show next button
        setTimeout(() => {
          this.showNext();
        }, this.animationDelay + 20);
      });
      
      // Add button to DOM
      this.root.appendChild(buttonElement);
      
      // Show button by increasing opacity
      buttonElement.style.opacity = 1;
      
    }
  };
  
  // Start the app
  controller.init();

}());
#tomato {
  background: tomato;
}

#blue {
  background: DeepSkyBlue;
}

.button {
  transition: opacity 0.5s ease-in-out;
  width: 100%;
  height: 50vh;
  border: solid 3px black;
  cursor: pointer;
}
<div id="root"></div>

【问题讨论】:

    标签: javascript html css css-transitions opacity


    【解决方案1】:

    这应该可以,代码笔链接:http://codepen.io/saa93/pen/gLbvmQ

    您需要添加它而不是直接将不透明度设置为 1

    // Show button by increasing opacity
    buttonElement.style.opacity = 0;
    setTimeout(() => {
        buttonElement.style.opacity = 1;
    }, this.animationDelay + 20);   
    

    【讨论】:

    • 太好了,它有效!你知道我为什么需要在 setTimeout 内部这样做吗?
    • 由于我们动态地分配转换和属性值(不透明度为 0),我们需要延迟浏览器,以便它可以将转换应用到元素。然后将不透明度添加到 1,我们得到了想要的效果。您可以在这里找到更详细的答案:stackoverflow.com/questions/8210560/…
    • 无论“this.animationDelay + 20”的值如何,其他人是否看到 0 延迟?
    【解决方案2】:

    this.root.appendChild(buttonElement);之后

    您应该将不透明度设置为 0 并让浏览器有时间在buttonElement.style.opacity = 1; 之前渲染

    顺便说一句,我认为删除和添加元素不是一个好方法

    .button {
    
      width: 100%;
      height: 50vh;
      border: solid 3px black;
      cursor: pointer;
       animation-name: example;
        animation-duration:3.5s;
    
    }
    @keyframes example {
            0%   {opacity:1}
            50%  {opacity:0}
        100%  {opacity:1}
    
    }
    

    你真正想要的是使用这样的动画:JSFIDDLE EXAMPLE

    这样,动画只使用 css 来回完成所有这些时间和不透明度

    【讨论】:

    • 感谢您的帮助。我正在为单页应用程序执行此操作。基本上这个想法是当用户点击按钮时。整个屏幕会淡出,然后新屏幕会淡入。
    • @PiotrBerebecki 我仍然认为使用动画效果要好得多。
    • 谢谢,我会调查此事。
    【解决方案3】:

    添加一个类(在代码片段中是.active)添加以下内容:

    CSS

    .button {
      opacity: 0;
      transition: opacity 0.5s ease-in-out;
      width: 100%;
      height: 50vh;
      border: solid 3px black;
      cursor: pointer;
    }
    .button.active {
      opacity: 1;
      transition: opacity 0.5s ease-in-out;
    }
    

    JavaScript

      ...
      // Reduce opacity
      buttonElement.classList.toggle('active');
      buttonElement.style.opacity = 0;
      ...
      // Show button by increasing opacity
      buttonElement.classList.toggle('active');
      buttonElement.style.opacity = 1;
    

    片段

    console.clear();
    
    (function() {
    
      // Data for the app
      const model = {
        buttons: ['tomato', 'blue'],
        currentButton: -1
      };
    
      // Logig for the app
      const controller = {
        init: function() {
          view.init();
        },
        getButtonName: function() {
          model.currentButton = (model.currentButton + 1) % model.buttons.length;
          return model.buttons[model.currentButton];
        }
      };
    
      // View for the app
      const view = {
        init: function() {
          this.root = document.getElementById('root');
          this.showNext();
        },
    
        animationDelay: 500,
    
        showNext: function() {
          // Get next button name
          const buttonName = controller.getButtonName();
    
          // Create button DOM element
          const buttonElement = document.createElement('div');
          buttonElement.className = 'button';
          buttonElement.id = buttonName;
          buttonElement.textContent = buttonName;
          buttonElement.style.opacity = 0;
    
          // Add event listender for the button
          buttonElement.addEventListener('click', event => {
            // Reduce opacity
            buttonElement.classList.toggle('active');
            buttonElement.style.opacity = 0;
            // Remove the button from DOM
            setTimeout(() => {
    
              this.root.removeChild(buttonElement);
            }, this.animationDelay + 10);
            // Start the function to show next button
            setTimeout(() => {
              this.showNext();
            }, this.animationDelay + 20);
          });
    
          // Add button to DOM
          this.root.appendChild(buttonElement);
    
          // Show button by increasing opacity
          buttonElement.classList.toggle('active');
          buttonElement.style.opacity = 1;
    
        }
      };
    
      // Start the app
      controller.init();
    
    }());
    #tomato {
      background: tomato;
    }
    #blue {
      background: DeepSkyBlue;
    }
    .button {
      opacity: 0;
      transition: opacity 0.5s ease-in-out;
      width: 100%;
      height: 50vh;
      border: solid 3px black;
      cursor: pointer;
    }
    .button.active {
      opacity: 1;
      transition: opacity 0.5s ease-in-out;
    }
    <div id="root"></div>

    【讨论】:

    • 感谢您的帮助,Saa_keetin 的解决方案似乎更简单。此外,由于某种原因,当我在这里运行您的代码时,过渡没有平滑的淡入淡出。
    • 是的,您可以更改持续时间和缓动来满足您的需求。前任。 transition: opacity 1s linear Saa_keetin 的效率更高。我的提议很容易通过在 .active 类上使用 CSS 动画来扩展。
    猜你喜欢
    • 2021-10-12
    • 2014-02-04
    • 2013-12-17
    • 2019-03-26
    • 1970-01-01
    • 2018-04-25
    • 2017-06-27
    • 2021-07-26
    • 2013-07-01
    相关资源
    最近更新 更多