使用 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