使用 React 和 CSS 关闭屏幕时淡出动画
Fade out animation when closing a screen with React and CSS
我有一个简单的页面,点击一个按钮即可打开,并在打开时覆盖我的整个屏幕。
我让它在打开时淡入,但希望它在关闭时淡出。这怎么可能?
它的显示当前由我的组件状态控制,我使用 CSS' 关键帧动画。
这是我的应用目前的样例:
const App = () => {
const [opened, setOpened] = React.useState(false)
return (
<div>
<button className='btn' onClick={() => setOpened(!opened)}>{opened ? 'Close' : 'Open'}</button>
<div style={{margin: 50 }}>Some page content that will be covered</div>
<button onClick={() => console.warn('clicked')}>I need to be clickable when visible</button>
<div className={opened ? 'content': 'no-content'}>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<button>I do nothing</button>
<p>Tellus molestie nunc non blandit massa enim nec dui. Sapien et ligula ullamcorper malesuada proin libero nunc consequat interdum. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Nisi quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus. Sit amet commodo nulla facilisi nullam vehicula. Vestibulum lorem sed risus ultricies tristique. Sit amet nisl suscipit adipiscing bibendum est ultricies integer quis. Tempus egestas sed sed risus pretium quam vulputate dignissim. Feugiat vivamus at augue eget arcu dictum. Consequat interdum varius sit amet mattis vulputate enim nulla. Sit amet risus nullam eget. Id neque aliquam vestibulum morbi blandit cursus risus at ultrices. Massa tempor nec feugiat nisl pretium fusce id velit. Vestibulum morbi blandit cursus risus. Id diam vel quam elementum pulvinar etiam non. Faucibus a pellentesque sit amet porttitor eget dolor morbi. Dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim cras tincidunt. Lorem sed risus ultricies tristique. Viverra orci sagittis eu volutpat odio facilisis mauris.
</p>
</div>
</div>
)
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
body {
width: 500px;
height: 500px;
}
.btn {
position: fixed;
top: 0;
z-index: 9999
}
@keyframes fadeOut {
0% { opacity: 1 }
100% { opacity: 0 }
}
@keyframes fadeOut {
0% { opacity: 1 }
100% { opacity: 0 }
}
.no-content {
opacity: 0;
animation: fadeOut 500ms linear;
}
@keyframes fadeIn {
0% { opacity: 0 }
100% { opacity: 1 }
}
.content {
opacity: 1;
animation: fadeIn 1s linear;
position: absolute;
top:0;
right:0;
width: 100%;
height: 100%;
background-color: black;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
'.no-content' 显示:none
立即删除元素并且动画不发生
我刚刚删除了它,它工作得很好。
我添加了另一个 CSS 来固定 div 'I assumed you want it like this'
的位置
const App = () => {
const [opened, setOpened] = React.useState(false)
const overlay = document.getElementById('overlay');
const handleClick = ()=>{
setOpened(!opened)
if(overlay){
if(!opened) overlay.style.display = "block"
else{
setTimeout(() => {
overlay.style.display = 'none'
}, 1000) // animation time
}
}
}
return (
<div>
<button className='btn' onClick={handleClick }>{opened ? 'Close' : 'Open'}</button>
<div style={{margin: 50 }}>Some page content that will be covered</div>
<div id="overlay" className={opened ? 'content': 'no-content'}>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<button>I do nothing</button>
<p>Tellus molestie nunc non blandit massa enim nec dui. Sapien et ligula ullamcorper malesuada proin libero nunc consequat interdum. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Nisi quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus. Sit amet commodo nulla facilisi nullam vehicula. Vestibulum lorem sed risus ultricies tristique. Sit amet nisl suscipit adipiscing bibendum est ultricies integer quis. Tempus egestas sed sed risus pretium quam vulputate dignissim. Feugiat vivamus at augue eget arcu dictum. Consequat interdum varius sit amet mattis vulputate enim nulla. Sit amet risus nullam eget. Id neque aliquam vestibulum morbi blandit cursus risus at ultrices. Massa tempor nec feugiat nisl pretium fusce id velit. Vestibulum morbi blandit cursus risus. Id diam vel quam elementum pulvinar etiam non. Faucibus a pellentesque sit amet porttitor eget dolor morbi. Dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim cras tincidunt. Lorem sed risus ultricies tristique. Viverra orci sagittis eu volutpat odio facilisis mauris.
</p>
</div>
</div>
)
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
body {
width: 500px;
height: 500px;
}
.btn {
position: fixed;
top: 0;
z-index: 9999
}
@keyframes fadeOut {
0% { opacity: 1 }
100% { opacity: 0,
display: none
}
}
@keyframes fadeIn {
0% { opacity: 0 }
100% { opacity: 1 }
}
.no-content {
opacity: 0;
animation: fadeOut 500ms linear;
position: absolute;
top:0;
right:0;
width: 100%;
height: 100%;
background-color: black;
color: white;
}
.content {
opacity: 1;
animation: fadeIn 1s linear;
position: absolute;
top:0;
right:0;
width: 100%;
height: 100%;
background-color: black;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
您不需要动画,因为过渡更清晰
const App = () => {
const [opened, setOpened] = React.useState(false)
return ( <
div >
<
button className = 'btn'
onClick = {
() => setOpened(!opened)
} > {
opened ? 'Close' : 'Open'
} < /button> <
div style = {
{
margin: 50
}
} > Some page content that will be covered < /div> <
div className = {'content ' +(
opened ? 'show-content' : '')
} >
<
p >
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. <
/p> <
button > I do nothing < /button> <
p > Tellus molestie nunc non blandit massa enim nec dui.Sapien et ligula ullamcorper malesuada proin libero nunc consequat interdum.Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique.Nisi quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus.Sit amet commodo nulla facilisi nullam vehicula.Vestibulum lorem sed risus ultricies tristique.Sit amet nisl suscipit adipiscing bibendum est ultricies integer quis.Tempus egestas sed sed risus pretium quam vulputate dignissim.Feugiat vivamus at augue eget arcu dictum.Consequat interdum varius sit amet mattis vulputate enim nulla.Sit amet risus nullam eget.Id neque aliquam vestibulum morbi blandit cursus risus at ultrices.Massa tempor nec feugiat nisl pretium fusce id velit.Vestibulum morbi blandit cursus risus.Id diam vel quam elementum pulvinar etiam non.Faucibus a pellentesque sit amet porttitor eget dolor morbi.Dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim cras tincidunt.Lorem sed risus ultricies tristique.Viverra orci sagittis eu volutpat odio facilisis mauris. <
/p> <
/div> <
/div>
)
}
ReactDOM.render( <
App / > ,
document.getElementById('app')
);
body {
width: 500px;
height: 500px;
}
.btn {
position: fixed;
top: 0;
z-index: 999;
}
.content {
transition: 0.3s;
opacity:0;
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
background-color: black;
color: white;
}
.show-content {
opacity:1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
我有一个简单的页面,点击一个按钮即可打开,并在打开时覆盖我的整个屏幕。
我让它在打开时淡入,但希望它在关闭时淡出。这怎么可能?
它的显示当前由我的组件状态控制,我使用 CSS' 关键帧动画。
这是我的应用目前的样例:
const App = () => {
const [opened, setOpened] = React.useState(false)
return (
<div>
<button className='btn' onClick={() => setOpened(!opened)}>{opened ? 'Close' : 'Open'}</button>
<div style={{margin: 50 }}>Some page content that will be covered</div>
<button onClick={() => console.warn('clicked')}>I need to be clickable when visible</button>
<div className={opened ? 'content': 'no-content'}>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<button>I do nothing</button>
<p>Tellus molestie nunc non blandit massa enim nec dui. Sapien et ligula ullamcorper malesuada proin libero nunc consequat interdum. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Nisi quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus. Sit amet commodo nulla facilisi nullam vehicula. Vestibulum lorem sed risus ultricies tristique. Sit amet nisl suscipit adipiscing bibendum est ultricies integer quis. Tempus egestas sed sed risus pretium quam vulputate dignissim. Feugiat vivamus at augue eget arcu dictum. Consequat interdum varius sit amet mattis vulputate enim nulla. Sit amet risus nullam eget. Id neque aliquam vestibulum morbi blandit cursus risus at ultrices. Massa tempor nec feugiat nisl pretium fusce id velit. Vestibulum morbi blandit cursus risus. Id diam vel quam elementum pulvinar etiam non. Faucibus a pellentesque sit amet porttitor eget dolor morbi. Dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim cras tincidunt. Lorem sed risus ultricies tristique. Viverra orci sagittis eu volutpat odio facilisis mauris.
</p>
</div>
</div>
)
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
body {
width: 500px;
height: 500px;
}
.btn {
position: fixed;
top: 0;
z-index: 9999
}
@keyframes fadeOut {
0% { opacity: 1 }
100% { opacity: 0 }
}
@keyframes fadeOut {
0% { opacity: 1 }
100% { opacity: 0 }
}
.no-content {
opacity: 0;
animation: fadeOut 500ms linear;
}
@keyframes fadeIn {
0% { opacity: 0 }
100% { opacity: 1 }
}
.content {
opacity: 1;
animation: fadeIn 1s linear;
position: absolute;
top:0;
right:0;
width: 100%;
height: 100%;
background-color: black;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
'.no-content' 显示:none
立即删除元素并且动画不发生
我刚刚删除了它,它工作得很好。
我添加了另一个 CSS 来固定 div 'I assumed you want it like this'
的位置const App = () => {
const [opened, setOpened] = React.useState(false)
const overlay = document.getElementById('overlay');
const handleClick = ()=>{
setOpened(!opened)
if(overlay){
if(!opened) overlay.style.display = "block"
else{
setTimeout(() => {
overlay.style.display = 'none'
}, 1000) // animation time
}
}
}
return (
<div>
<button className='btn' onClick={handleClick }>{opened ? 'Close' : 'Open'}</button>
<div style={{margin: 50 }}>Some page content that will be covered</div>
<div id="overlay" className={opened ? 'content': 'no-content'}>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<button>I do nothing</button>
<p>Tellus molestie nunc non blandit massa enim nec dui. Sapien et ligula ullamcorper malesuada proin libero nunc consequat interdum. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Nisi quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus. Sit amet commodo nulla facilisi nullam vehicula. Vestibulum lorem sed risus ultricies tristique. Sit amet nisl suscipit adipiscing bibendum est ultricies integer quis. Tempus egestas sed sed risus pretium quam vulputate dignissim. Feugiat vivamus at augue eget arcu dictum. Consequat interdum varius sit amet mattis vulputate enim nulla. Sit amet risus nullam eget. Id neque aliquam vestibulum morbi blandit cursus risus at ultrices. Massa tempor nec feugiat nisl pretium fusce id velit. Vestibulum morbi blandit cursus risus. Id diam vel quam elementum pulvinar etiam non. Faucibus a pellentesque sit amet porttitor eget dolor morbi. Dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim cras tincidunt. Lorem sed risus ultricies tristique. Viverra orci sagittis eu volutpat odio facilisis mauris.
</p>
</div>
</div>
)
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
body {
width: 500px;
height: 500px;
}
.btn {
position: fixed;
top: 0;
z-index: 9999
}
@keyframes fadeOut {
0% { opacity: 1 }
100% { opacity: 0,
display: none
}
}
@keyframes fadeIn {
0% { opacity: 0 }
100% { opacity: 1 }
}
.no-content {
opacity: 0;
animation: fadeOut 500ms linear;
position: absolute;
top:0;
right:0;
width: 100%;
height: 100%;
background-color: black;
color: white;
}
.content {
opacity: 1;
animation: fadeIn 1s linear;
position: absolute;
top:0;
right:0;
width: 100%;
height: 100%;
background-color: black;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
您不需要动画,因为过渡更清晰
const App = () => {
const [opened, setOpened] = React.useState(false)
return ( <
div >
<
button className = 'btn'
onClick = {
() => setOpened(!opened)
} > {
opened ? 'Close' : 'Open'
} < /button> <
div style = {
{
margin: 50
}
} > Some page content that will be covered < /div> <
div className = {'content ' +(
opened ? 'show-content' : '')
} >
<
p >
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. <
/p> <
button > I do nothing < /button> <
p > Tellus molestie nunc non blandit massa enim nec dui.Sapien et ligula ullamcorper malesuada proin libero nunc consequat interdum.Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique.Nisi quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus.Sit amet commodo nulla facilisi nullam vehicula.Vestibulum lorem sed risus ultricies tristique.Sit amet nisl suscipit adipiscing bibendum est ultricies integer quis.Tempus egestas sed sed risus pretium quam vulputate dignissim.Feugiat vivamus at augue eget arcu dictum.Consequat interdum varius sit amet mattis vulputate enim nulla.Sit amet risus nullam eget.Id neque aliquam vestibulum morbi blandit cursus risus at ultrices.Massa tempor nec feugiat nisl pretium fusce id velit.Vestibulum morbi blandit cursus risus.Id diam vel quam elementum pulvinar etiam non.Faucibus a pellentesque sit amet porttitor eget dolor morbi.Dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim cras tincidunt.Lorem sed risus ultricies tristique.Viverra orci sagittis eu volutpat odio facilisis mauris. <
/p> <
/div> <
/div>
)
}
ReactDOM.render( <
App / > ,
document.getElementById('app')
);
body {
width: 500px;
height: 500px;
}
.btn {
position: fixed;
top: 0;
z-index: 999;
}
.content {
transition: 0.3s;
opacity:0;
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
background-color: black;
color: white;
}
.show-content {
opacity:1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>