Javascript 在ReactJS中处理set/removeAttribute和添加类列表的更好方法
我已经创建了一个自定义手风琴-完整的工作视图 这是我的Javascript 在ReactJS中处理set/removeAttribute和添加类列表的更好方法,javascript,html,css,reactjs,Javascript,Html,Css,Reactjs,我已经创建了一个自定义手风琴-完整的工作视图 这是我的handleClick功能,当你点击每个手风琴时可以使用。我需要一个动画(打开和关闭内容时),所以这就是我尝试的。我不确定这是否是一种接近我想要实现的目标的反应方式 关于如何使此函数更具反应性,有什么建议吗 const handleClick = (e) => { e.preventDefault(); const accordion = e.target.parentNode; const content
handleClick
功能,当你点击每个手风琴时可以使用。我需要一个动画(打开和关闭内容时),所以这就是我尝试的。我不确定这是否是一种接近我想要实现的目标的反应方式
关于如何使此函数更具反应性,有什么建议吗
const handleClick = (e) => {
e.preventDefault();
const accordion = e.target.parentNode;
const content = accordion.querySelector(".content");
if (accordion.hasAttribute("open")) {
content.style.removeProperty("max-height");
content.classList.add("closed");
setTimeout(() => {
accordion.removeAttribute("open");
}, 400);
return;
}
// If the <details> element is closed, add the [open] attribute (so the content will render), and animate in
accordion.setAttribute("open", "");
// Get proper max-height for element for better animation
if (!content.getAttribute("data-height")) {
content.style.maxHeight = "none";
content.setAttribute(
"data-height",
`${content.getBoundingClientRect().height}px`
);
content.style.removeProperty("max-height");
}
// Wait for the browser to apply [open] to <details>, then animate
setTimeout(() => {
content.classList.remove(["closed"]);
content.style.maxHeight = content.getAttribute("data-height");
}, 0);
};
const handleClick=(e)=>{
e、 预防默认值();
const accordion=e.target.parentNode;
常量内容=accordion.querySelector(“.content”);
if(accordion.hasAttribute(“打开”)){
content.style.removeProperty(“最大高度”);
content.classList.add(“已关闭”);
设置超时(()=>{
手风琴。删除属性(“打开”);
}, 400);
返回;
}
//如果元素已关闭,请添加[open]属性(以便内容将渲染),并在中设置动画
accordion.setAttribute(“打开”、“打开”);
//为元素获取适当的最大高度,以获得更好的动画效果
如果(!content.getAttribute(“数据高度”)){
content.style.maxHeight=“无”;
content.setAttribute(
“数据高度”,
`${content.getBoundingClientRect().height}px`
);
content.style.removeProperty(“最大高度”);
}
//等待浏览器应用[打开],然后设置动画
设置超时(()=>{
content.classList.remove([“closed”]);
content.style.maxHeight=content.getAttribute(“数据高度”);
}, 0);
};
我建议在渲染方法中使用状态并解释这些状态,而不是通过选择器设置属性,例如:
const [accordionOpened, setAccordionOpened] = useState(false);
{
title: "Lorem ipsum dolor sit amet",
content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed pretium sagittis quam vitae commodo. Nulla et ligula non nunc ornare consectetur.",
opened: false,
}
如果手风琴打开或关闭,将用布尔值表示
因为您的手风琴中有多个项目,所以这不是您想要的,因为您必须为手风琴中的项目数量复制此状态
我会在您的数据项中添加一个字段,例如:
const [accordionOpened, setAccordionOpened] = useState(false);
{
title: "Lorem ipsum dolor sit amet",
content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed pretium sagittis quam vitae commodo. Nulla et ligula non nunc ornare consectetur.",
opened: false,
}
将在渲染方法中对其进行解释,如:
{item.opened ? <p className={"openedContent"}>{item.content}</p> : null}
{item.opened?{item.content}
:null}
然后,您将能够摆脱那些在handleClick中设置的无关的关闭和打开属性。在React中,您永远不会直接更新UI。而是更新状态,然后告诉React如何将该状态映射到UI 考虑将手风琴分为两个部分-一个
手风琴
和一个手风琴项目
。然后,你有一个这样的结构:
const AccordionItem = ({ title, content, toggle, open }) => (
<details open={open} onClick={toggle}>
<summary>{title}</summary>
<p>{content}</p>
</details>
);
export const Accordion = (props) => {
const [items, setItems] = useState(
props.items.map((item) => ({
...item,
open: false
}))
);
const toggleItem = (idx) => (e) => {
e.preventDefault();
setItems([
...items.slice(0, idx),
{ ...items[idx], open: !items[idx].open },
...items.slice(idx + 1)
]);
};
return items.map((item, idx) => (
<AccordionItem key={idx} toggle={toggleItem(idx)} {...item} />
));
};
const AccordionItem=({title,content,toggle,open})=>(
{title}
{content}
);
导出常数手风琴=(道具)=>{
const[items,setItems]=useState(
道具.道具.地图((道具)=>({
…项目,
开放:假
}))
);
常量切换项=(idx)=>(e)=>{
e、 预防默认值();
设置项([
…items.slice(0,idx),
{…items[idx],打开:!items[idx].open},
…items.slice(idx+1)
]);
};
返回items.map((item,idx)=>(
,但是有很多关于如何在React中使用refs的文章,所以我在这里不详细介绍
谢谢你的建议。我尝试过你的例子,尝试过在打开和关闭时添加动画-它不起作用。我尝试过各种方法,但无法复制动画。我做错了什么?