当我关闭div并且div应该变小时,此代码很好用,但是当我尝试打开div时动画不起作用。为什么会这样,我该怎么做呢?
const Container = styled.div`
margin: 5px;
padding: 10px;
width: 200px;
max-height: ${props => (props.open ? '500px' : '20px')};
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
transition: max-height 1s cubic-bezier(0, 1, 0.5, 1);
background-color: #f6f6f6;
cursor: pointer;
`;
我希望具有自动高度,但是我读到您可以将max-height设置为比您期望的div更大的高度。缺点是当动画时间为1s时,即使高度小于最大高度,动画也将使用1s来设置最大高度的动画。
答案 0 :(得分:0)
let isActive = true;
document.getElementById("toggle").addEventListener("click", function(e) {
document.getElementById("cont").style.height = isActive ? document.getElementById("cont").scrollHeight + "px" : 0;
isActive = !isActive;
});
.container {
width: 100%;
padding: 0;
height: 0;
transition: 1s;
overflow: hidden;
}
.container-text {
padding: 10px;
background: green;
}
<button id="toggle">Toggle</button>
<div class="container" id="cont">
<div class="container-text">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Facere culpa aliquid neque atque aliquam dolorem molestiae ad, optio laborum, vitae aperiam vel explicabo distinctio similique id, eos reprehenderit inventore repudiandae!
</div>
</div>
答案 1 :(得分:0)
抱歉,height='auto'
上的动画非常“无聊”:P因此,如果您希望Toggle书写始终可见,建议您查看已经存在的Component,例如→https://springload.github.io/react-accessible-accordion/
它们很多,您可以使用诸如react toggle
,react accordion
和react slidedown
(或这些的组合:)之类的关键字找到它们
相反,如果您希望在长文本出现时隐藏Toggle书写,那么我为您编写了一个Component(您可以改进它的更多想法,但我认为它已满足您的要求)→{{3} }
这个想法很简单,可以在以下算法中看到:
Toggle
组件是通过将isOpen
属性设置为true
来构造的,因此将呈现长文本。
在componentDidMount
中,将长文本所需的高度保存在状态属性fullOpenHeight
中,并且isOpen
属性设置为false
。
自componentDidMount
起更新状态以来,Toggle已用短文本呈现,并且已调用componentDidUpdate
。这样,自checkInitialHeights
起,我们在Component的状态下保存带有短文本的Component的高度,并将te的checkInitialHeights
属性设置为false
。
再次重新渲染了该组件,现在可以使用它了。请注意,如果您在切换开关完全关闭/完全打开之前再次单击它,我也会使用closeHeight
和openHeight
属性获得不错的反馈。
希望有帮助!这里也是小提琴。
const animation = (isOpen, closeHeight, openHeight, fullCloseHeight, fullOpenHeight) => {
if (isOpen && closeHeight !== null && openHeight !== null) {
return `${slideDown(closeHeight, fullOpenHeight)} 1s linear`;
}
if (!isOpen && closeHeight !== null && openHeight !== null) {
return `${slideUp(fullCloseHeight, openHeight)} 1s linear`;
}
return "";
}
const slideDown = (closeHeight, openHeight) => styled.keyframes `
0% { height: ${closeHeight}px }
0.1% { height: ${closeHeight}px }
100% { height: ${openHeight}px }
`;
const slideUp = (closeHeight, openHeight) => styled.keyframes `
0% { height: ${openHeight}px }
0.1% { height: ${openHeight}px }
100% { height: ${closeHeight}px }
`;
const Container = styled.default.div `
margin: 5px;
padding: 10px;
width: 200px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
background-color: #f6f6f6;
cursor: pointer;
box-sizing: border-box;
animation : ${props => animation(props.toggleState.isOpen, props.toggleState.closeHeight, props.toggleState.openHeight, props.toggleState.fullCloseHeight, props.toggleState.fullOpenHeight)}
overflow: hidden;
`;
class Toggle extends React.Component {
toggleDOM;
constructor(props) {
super(props);
this.state = {
isOpen: true,
checkInitialHeights: true,
closeHeight: null,
openHeight: null,
fullCloseHeight: null,
fullOpenHeight: null
};
this.toggleDOM = React.createRef();
}
handleToggle = (e) => {
const {
isOpen
} = this.state;
const currHeight = this.toggleDOM.current.getBoundingClientRect().height;
if (!isOpen) {
this.setState({
isOpen: true,
closeHeight: currHeight
});
} else {
this.setState({
isOpen: false,
openHeight: currHeight
});
}
}
componentDidMount() {
const toggleDOM = this.toggleDOM.current;
const fullOpenHeight = toggleDOM.getBoundingClientRect().height;
this.setState({
fullOpenHeight,
isOpen: false
});
}
componentDidUpdate() {
const toggleDOM = this.toggleDOM.current;
const {
isOpen,
closeHeight,
openHeight,
checkInitialHeights
} = this.state;
if (checkInitialHeights) {
const fullCloseHeight = toggleDOM.getBoundingClientRect().height;
this.setState({
fullCloseHeight,
checkInitialHeights: false
});
return;
}
if (isOpen && openHeight === null) {
const newOpenHeight = this.toggleDOM.current.getBoundingClientRect().height;
this.setState({
openHeight: newOpenHeight
});
}
}
render() {
return ( <
Container innerRef = {
this.toggleDOM
}
onClick = {
this.handleToggle
}
toggleState = {
this.state
} > {
this.state.isOpen ?
this.props.children :
this.props.title
} <
/Container>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isToggleOpen: false
};
}
handleToggle = (e) => {
this.setState(prevState => ({
isToggleOpen: !prevState.isToggleOpen
}));
}
render() {
return ( <
Toggle title = "Spoiler" >
<
p >
Lorem Ipsum < br / >
Lorem Ipsum < br / >
Lorem Ipsum < br / >
Lorem Ipsum < br / >
Lorem Ipsum < br / >
Lorem Ipsum < br / >
Lorem Ipsum < br / >
Lorem Ipsum < br / >
<
/p> <
/Toggle>
);
}
}
ReactDOM.render( < App / > , document.getElementById("root"));
@import url(https://fonts.googleapis.com/css?family=Montserrat);
body {
font-family: 'Montserrat', sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.2/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/styled-components/3.4.10/styled-components.min.js"></script>
<div id="root"></div>