Javascript 展开/折叠所有数据
我正在做一个手风琴,当我们点击每个单独的项目,然后它的开始或结束以及 现在我已经实现了expandall或collapseall选项,以使所有手风琴展开/折叠 Accordion.jsJavascript 展开/折叠所有数据,javascript,css,reactjs,accordion,collapse,Javascript,Css,Reactjs,Accordion,Collapse,我正在做一个手风琴,当我们点击每个单独的项目,然后它的开始或结束以及 现在我已经实现了expandall或collapseall选项,以使所有手风琴展开/折叠 Accordion.js const accordionArray = [ { heading: "Heading 1", text: "Text for Heading 1" }, { heading: "Heading 2", text: "Te
const accordionArray = [
{ heading: "Heading 1", text: "Text for Heading 1" },
{ heading: "Heading 2", text: "Text for Heading 2" },
{ heading: "Heading 3", text: "Text for Heading 3" }
];
.
.
.
{accordionArray.map((item, index) => (
<div key={index}>
<Accordion>
<Heading>
<div className="heading-box">
<h1 className="heading">{item.heading}</h1>
</div>
</Heading>
<Text expandAll={expandAll}>
<p className="text">{item.text}</p>
</Text>
</Accordion>
</div>
))}
要求:
如果单击“全部展开/全部折叠”按钮,则应分别打开/关闭所有手风琴
无论以前打开/关闭的手风琴如何,这都应起作用。。因此,如果“全部展开”,则应打开所有手风琴,否则需要关闭所有手风琴,即使之前已打开/关闭
链接:
这是道具实际传递到的文件的链接
编辑:
如果我使用{this.props.children}
那么每个手风琴都会打开。。没有问题
但是,如果我在单击特定项目时手动打开任何手风琴,那么如果我单击“全部展开”,则其已展开(预期),但如果我单击“全部折叠”选项,则不是所有手风琴都关闭。。我们之前打开的那些仍处于打开状态。。但此处的预期行为是所有内容都应关闭。在这种情况下,this.props.render不是函数,this.props.text未定义,请尝试替换此行
<div className={`content open`}>
{this.props.render && this.props.render(this.props.text)}
</div>
{this.props.render&&this.props.render(this.props.text)}
据此:
<div className={`content open`}>
{this.props.children}
</div>
{this.props.children}
编辑://
另一种解决方案是将expandAll属性传递给Accordion组件
<Accordion expandAll={expandAll}>
<Heading>
<div className="heading-box">
<h1 className="heading">{item.heading}</h1>
</div>
</Heading>
<Text>
<p className="text">{item.text}</p>
</Text>
</Accordion>
{项目标题}
{item.text}
然后在getAccordion.js中
onShow = (i) => {
this.setState({
active: this.props.expandAll ? -1: i,
reserve: this.props.expandAll ? -1: i
});
if (this.state.reserve === i) {
this.setState({
active: -1,
reserve: -1
});
}
};
render() {
const children = React.Children.map(this.props.children, (child, i) => {
return React.cloneElement(child, {
heading: this.props.expandAll || this.state.active === i,
text: this.props.expandAll || this.state.active + stage === i,
onShow: () => this.onShow(i)
});
});
return <div className="accordion">{children}</div>;
}
};
onShow=(i)=>{
这是我的国家({
主动:这个。道具。全部?-1:i,
预备队:这个。道具。全部?-1:我
});
if(this.state.reserve==i){
这是我的国家({
主动:-1,
储备:-1
});
}
};
render(){
const children=React.children.map(this.props.children,(child,i)=>{
返回React.cloneElement(子级{
标题:this.props.expandAll | | this.state.active==i,
text:this.props.expandAll | | this.state.active+stage==i,
onShow:()=>这个.onShow(i)
});
});
返回{children};
}
};
在您的text.js文件中
在第9行。请将以前的代码替换为:
{this.props.children}
在沙箱里试过,为我工作
///
无法添加注释,因此无法编辑答案本身。
accorbian.js包含您的hook expandAll,标题boolean已经出现在getaccorbian.js中。
我建议将expand all移动到getaccorbian.js,以便您可以控制这两个值。基于@lissettdm answer,我不清楚为什么
getAccordion
和accordion
是两个独立的实体。您可能有一个非常合理的分离原因,但这两个组件的状态是相互依赖的,这一事实暗示,它们最好作为一个组件来实现
手风琴现在像以前一样直接控制其子对象的状态,但不使用getAccordion。切换expandAll现在也会重置各个项目的状态
const NormalAccordion = () => {
const accordionArray = [ //... your data ];
const [state, setState] = useState({
expandAll: false,
...accordionArray.map(item => false),
});
const handleExpandAll = () => {
setState((prevState) => ({
expandAll: !prevState.expandAll,
...accordionArray.map(item => !prevState.expandAll),
}));
};
const handleTextExpand = (id) => {
setState((prevState) => ({
...prevState,
[id]: !prevState[id]
}));
};
return (
<>
<div className="w-full text-right">
<button onClick={handleExpandAll}>
{state.expandAll ? `Collapse All` : `Expand All`}
</button>
</div>
<br />
{accordionArray.map((item, index) => (
<div key={index}>
<div className="accordion">
<Heading handleTextExpand={handleTextExpand} id={index}>
<div className="heading-box">
<h1 className="heading">{item.heading}</h1>
</div>
</Heading>
<Text shouldExpand={state[index]}>
<p className="text">{item.text}</p>
</Text>
</div>
</div>
))}
</>
);
};
const NormalAccordion=()=>{
const accordionArray=[/…您的数据];
常量[状态,设置状态]=使用状态({
全部:错,
…accordiogray.map(项=>false),
});
常量handleExpandAll=()=>{
设置状态((prevState)=>({
expandAll:!prevState.expandAll,
…accordiogray.map(项=>!prevState.expandAll),
}));
};
const handlettextexpand=(id)=>{
设置状态((prevState)=>({
…国家,
[id]:!prevState[id]
}));
};
返回(
{state.expandAll?`Collapse All`:`Expand All`}
{accordiogray.map((项目,索引)=>(
{项目标题}
{item.text}
))}
);
};
Heading返回索引,以便父组件知道要关闭哪个项
class Heading extends React.Component {
handleExpand = () => {
this.props.handleTextExpand(this.props.id);
};
render() {
return (
<div
style={ //... your styles}
onClick={this.handleExpand}
>
{this.props.children}
</div>
);
}
}
类标题扩展了React.Component{
handleExpand=()=>{
this.props.handletexpand(this.props.id);
};
render(){
返回(
{this.props.children}
);
}
}
文本只关心一个道具,以确定它是否应该显示展开内容
class Text extends React.Component {
render() {
return (
<div style={{ ...this.props.style }}>
<div
className={`content ${this.props.shouldExpand ? "open" : ""}`}
>
{this.props.shouldExpand ? this.props.children : ""}
</div>
</div>
);
}
}
类文本扩展React.Component{
render(){
返回(
{this.props.shouldExpand?this.props.children:}
);
}
}
谢谢您的回答。。但在这里,如果我点击标题2,点击“全部展开”,那么所有内容都会被打开,这样就可以了。。但是,如果我使全部折叠,标题2仍然打开,而它应该折叠全部手风琴。同样,如果我手动打开全部手风琴并单击“展开全部”,则不会发生任何情况(预期)。但如果我再次单击“全部折叠”,则没有手风琴关闭,所有内容仍然打开。。那么,你能帮我修复手动打开和折叠所有内容的问题吗?再次感谢,我已经通过getAccordion.js中的componentDidUpdate
mentod实现了这一点,就像这里通过将道具传递给Accordion一样。但是我已经在这里实现了你的解决方案,如果我们扩展,还有一个问题所有的手风琴,然后它是不可能关闭手动点击任何特定的手风琴。是的,你的解决方案看起来更好;)谢谢你的回答。。但在这里,如果我点击标题2,点击“全部展开”,那么所有内容都会被打开,这样就可以了。。但是,如果我使全部折叠,标题2仍然打开,而它应该折叠全部手风琴。同样,如果我手动打开全部手风琴并单击“展开全部无任何内容”
class Heading extends React.Component {
handleExpand = () => {
this.props.handleTextExpand(this.props.id);
};
render() {
return (
<div
style={ //... your styles}
onClick={this.handleExpand}
>
{this.props.children}
</div>
);
}
}
class Text extends React.Component {
render() {
return (
<div style={{ ...this.props.style }}>
<div
className={`content ${this.props.shouldExpand ? "open" : ""}`}
>
{this.props.shouldExpand ? this.props.children : ""}
</div>
</div>
);
}
}