使用 css 过渡和 vanilla JavaScript 更改不透明度仅在淡出时有效

Posted

技术标签:

【中文标题】使用 css 过渡和 vanilla JavaScript 更改不透明度仅在淡出时有效【英文标题】:Change of opacity using css transition and vanilla JavaScript works only when fading out 【发布时间】: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>

【问题讨论】:

【参考方案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,我们得到了想要的效果。您可以在这里找到更详细的答案:***.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 动画来扩展。

以上是关于使用 css 过渡和 vanilla JavaScript 更改不透明度仅在淡出时有效的主要内容,如果未能解决你的问题,请参考以下文章

css Vanilla CSS来自http://www.cssreset.com/scripts/vanilla-css-un-reset/,在CSS重置后使用,为所有人定义“默认”样式。

在给定 CSS 选择器的情况下查找 DOM 元素的 Vanilla JavaScript 函数

scss Vanilla CSS媒体查询+ Sass媒体查询mixin

CodeMirror与Vanilla TypeScript和WebPack

如何在 .NET Core MVC 中初始化或调用 Vanilla 数据表

如何触发css3过渡动画