在 Tailwind/Alpine.js 手风琴上切换 class
Toggling a class on a Tailwind/Alpine.js accordion
我用 TailwindCSS 和 Alpine.js 创建了一个手风琴,除了我还想更改按钮中的图标以在单击时展开内容外,它工作正常。
这是我的:
<div x-data="{selected:null,open:true}">
<dl class="faqs mx-auto max-w-2xl">
<dt>
<span class="faq-q">Question</span>
<button
type="button"
class="faq-toggle"
@click="selected !== 1 ? selected = 1 : selected = null, open = open"
:class="{ 'faq-open': open, 'faq-close': !(open) }"
>
<span>+</span>
<span class="hidden">-</span>
</button>
</dt>
<dd
class="faq-a overflow-hidden transition-all max-h-0 duration-700"
style="" x-ref="container1" x-bind:style="selected == 1 ? 'max-height: ' + $refs.container1.scrollHeight + 'px' : ''"
>
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
</div>
</dd>
</dl>
</div>
和 link 到 CodePen。
我想要做的是在单击按钮时将按钮的 class 从 faq-open
切换为 faq-close
。尽管我实际上可能也需要在父级 dt
上切换 class。
目前,单击按钮时手风琴展开,但 class 没有改变。
问题出在这一行
@click="selected !== 1 ? selected = 1 : selected = null, open = open"
你永远不会改变open
的值,它总是初始化时的值,即open: true
。
你需要切换它:
@click="selected !== 1 ? selected = 1 : selected = null, open = !open"
顺便说一句,你不需要额外的变量selected
来控制隐藏文本,一个open
变量就足够了。像这样:
<div x-data="{open: true}">
<dl class="faqs mx-auto max-w-2xl">
<dt>
<span class="faq-q">Question</span>
<button
type="button"
class="faq-toggle"
@click="open = !open"
:class="open ? 'faq-open' : 'faq-close'"
>
<span :class="open ? '' : 'hidden'">+</span>
<span :class="open ? 'hidden' : ''">-</span>
</button>
</dt>
<dd
class="faq-a overflow-hidden transition-all max-h-0 duration-700"
style="" x-ref="container1" x-bind:style="open ? 'max-height: ' + $refs.container1.scrollHeight + 'px' : ''"
>
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
</div>
</dd>
</dl>
import 'twin.macro';
import React, { useRef, useState } from 'react';
import { BiPlus, BiMinus } from 'react-icons/bi';
const Accordion = ({ title, children }) => {
const [active, setActive] = useState(false);
const [height, setHeight] = useState('0px');
const contentSpace = useRef(null);
function toggleAccordion() {
setActive(!active);
setHeight(active ? '0px' : `${contentSpace.current?.scrollHeight}px`);
}
return (
<div tw="flex flex-col outline-none" role="button" tabIndex={0}>
<div
tw="flex flex-row items-center justify-between py-4 border-b border-t border-black "
onClick={toggleAccordion}>
<h1 tw="cursor-pointer text-base font-bold">{title}</h1>
{active ? <BiMinus /> : <BiPlus />}
</div>
<div
ref={contentSpace}
style={{ maxHeight: `${height}` }}
tw="overflow-auto overflow-y-hidden duration-700 ease-in-out">
<p tw="my-4">{children}</p>
</div>
</div>
);
};
export default Accordion;
我用 TailwindCSS 和 Alpine.js 创建了一个手风琴,除了我还想更改按钮中的图标以在单击时展开内容外,它工作正常。
这是我的:
<div x-data="{selected:null,open:true}">
<dl class="faqs mx-auto max-w-2xl">
<dt>
<span class="faq-q">Question</span>
<button
type="button"
class="faq-toggle"
@click="selected !== 1 ? selected = 1 : selected = null, open = open"
:class="{ 'faq-open': open, 'faq-close': !(open) }"
>
<span>+</span>
<span class="hidden">-</span>
</button>
</dt>
<dd
class="faq-a overflow-hidden transition-all max-h-0 duration-700"
style="" x-ref="container1" x-bind:style="selected == 1 ? 'max-height: ' + $refs.container1.scrollHeight + 'px' : ''"
>
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
</div>
</dd>
</dl>
</div>
和 link 到 CodePen。
我想要做的是在单击按钮时将按钮的 class 从 faq-open
切换为 faq-close
。尽管我实际上可能也需要在父级 dt
上切换 class。
目前,单击按钮时手风琴展开,但 class 没有改变。
问题出在这一行
@click="selected !== 1 ? selected = 1 : selected = null, open = open"
你永远不会改变open
的值,它总是初始化时的值,即open: true
。
你需要切换它:
@click="selected !== 1 ? selected = 1 : selected = null, open = !open"
顺便说一句,你不需要额外的变量selected
来控制隐藏文本,一个open
变量就足够了。像这样:
<div x-data="{open: true}">
<dl class="faqs mx-auto max-w-2xl">
<dt>
<span class="faq-q">Question</span>
<button
type="button"
class="faq-toggle"
@click="open = !open"
:class="open ? 'faq-open' : 'faq-close'"
>
<span :class="open ? '' : 'hidden'">+</span>
<span :class="open ? 'hidden' : ''">-</span>
</button>
</dt>
<dd
class="faq-a overflow-hidden transition-all max-h-0 duration-700"
style="" x-ref="container1" x-bind:style="open ? 'max-height: ' + $refs.container1.scrollHeight + 'px' : ''"
>
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
</div>
</dd>
</dl>
import 'twin.macro';
import React, { useRef, useState } from 'react';
import { BiPlus, BiMinus } from 'react-icons/bi';
const Accordion = ({ title, children }) => {
const [active, setActive] = useState(false);
const [height, setHeight] = useState('0px');
const contentSpace = useRef(null);
function toggleAccordion() {
setActive(!active);
setHeight(active ? '0px' : `${contentSpace.current?.scrollHeight}px`);
}
return (
<div tw="flex flex-col outline-none" role="button" tabIndex={0}>
<div
tw="flex flex-row items-center justify-between py-4 border-b border-t border-black "
onClick={toggleAccordion}>
<h1 tw="cursor-pointer text-base font-bold">{title}</h1>
{active ? <BiMinus /> : <BiPlus />}
</div>
<div
ref={contentSpace}
style={{ maxHeight: `${height}` }}
tw="overflow-auto overflow-y-hidden duration-700 ease-in-out">
<p tw="my-4">{children}</p>
</div>
</div>
);
};
export default Accordion;