Bento 手风琴
<head>
<meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <script src="https://cdn.ampproject.org/bento.js"></script> <script async src="https://cdn.ampproject.org/v0/bento-accordion-1.0.js" ></script> <link rel="stylesheet" type="text/css" href="https://cdn.ampproject.org/v0/bento-accordion-1.0.css" /> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background: #ecf1f3; } .my-accordion > section { border-radius: 0.5rem; margin: 1rem; background: white; background-repeat: no-repeat; background-position: right 1rem top 1rem; } .my-accordion h2 { background: white; padding: 2rem; border: none; background: none; } .my-accordion div { padding: 2rem; padding-top: 0; } .my-accordion section[expanded] { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48px' viewBox='0 0 24 24' width='48px' fill='%23000000'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath d='M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14l-6-6z'/%3E%3C/svg%3E%0A"); } .my-accordion section:not([expanded]) { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48px' viewBox='0 0 24 24' width='48px' fill='%23000000'%3E%3Cpath d='M24 24H0V0h24v24z' fill='none' opacity='.87'/%3E%3Cpath d='M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6-1.41-1.41z'/%3E%3C/svg%3E%0A"); } </style>
</head>
<body>
<bento-accordion id="my-accordion" class="my-accordion"> <section> <h2>Section 1</h2> <div>Content in section 1.</div> </section> <section> <h2>Section 2</h2> <div>Content in section 2.</div> </section> <section expanded> <h2>Section 3</h2> <div>Content in section 3.</div> </section> </bento-accordion>
</body>
显示可折叠和展开的内容部分。此组件为查看者提供了一种浏览内容大纲并跳转到任意部分的方法。有效使用可减少移动设备上的滚动需求。
- Bento 手风琴接受一个或多个
<section>
元素作为其直接子元素。 - 每个
<section>
必须恰好包含两个直接子元素。 <section>
中的第一个子元素是 Bento 手风琴该部分的标题。它必须是标题元素,例如<h1>-<h6>
或<header>
。<section>
中的第二个子元素是可展开/可折叠内容。- 它可以是 AMP HTML 中允许的任何标签。
- 点击或轻触
<section>
标题可展开或折叠该部分。 - 具有已定义
id
的 Bento 手风琴在用户停留在您的域名时保留每个部分的折叠或展开状态。
Web 组件
您必须包含每个 Bento 组件所需的 CSS 库,以保证正确加载,然后才能添加自定义样式。或使用可内嵌的轻量级预升级样式。请参阅 布局和样式。
通过 npm 导入
npm install @bentoproject/accordion
import {defineElement as defineBentoAccordion} from '@bentoproject/accordion';
defineBentoAccordion();
通过 <script>
包含
<script type="module" src="https://cdn.ampproject.org/bento.mjs" crossorigin="anonymous"></script>
<script nomodule src="https://cdn.ampproject.org/bento.js" crossorigin="anonymous"></script>
<script type="module" src="https://cdn.ampproject.org/v0/bento-accordion-1.0.mjs" crossorigin="anonymous"></script>
<script nomodule src="https://cdn.ampproject.org/v0/bento-accordion-1.0.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.ampproject.org/v0/bento-accordion-1.0.css" crossorigin="anonymous">
示例
<head>
<script type="module" async src="https://cdn.ampproject.org/bento.mjs" ></script> <script nomodule src="https://cdn.ampproject.org/bento.js"></script> <script type="module" async src="https://cdn.ampproject.org/v0/bento-accordion-1.0.mjs" ></script> <script nomodule async src="https://cdn.ampproject.org/v0/bento-accordion-1.0.js" ></script> <link rel="stylesheet" type="text/css" href="https://cdn.ampproject.org/v0/bento-accordion-1.0.css" />
</head>
<body>
<bento-accordion id="my-accordion"> <section> <h2>Section 1</h2> <div>Content in section 1.</div> </section> <section> <h2>Section 2</h2> <div>Content in section 2.</div> </section> <!-- Expanded on page load due to attribute: --> <section expanded> <h2>Section 3</h2> <div>Content in section 3.</div> </section> </bento-accordion>
</body>
交互性和 API 使用
Bento 组件通过其 API 具有很强的交互性。bento-accordion
组件 API 可通过在您的文档中包含以下脚本标签来访问
await customElements.whenDefined('bento-accordion');
const api = await accordion.getApi();
API 示例
<head>
<script type="module" async src="https://cdn.ampproject.org/bento.mjs" ></script> <script nomodule src="https://cdn.ampproject.org/bento.js"></script> <script type="module" async src="https://cdn.ampproject.org/v0/bento-accordion-1.0.mjs" ></script> <script nomodule async src="https://cdn.ampproject.org/v0/bento-accordion-1.0.js" ></script> <link rel="stylesheet" type="text/css" href="https://cdn.ampproject.org/v0/bento-accordion-1.0.css" />
</head>
<body>
<bento-accordion id="my-accordion"> <section> <h2>Section 1</h2> <div>Content in section 1.</div> </section> <section> <h2>Section 2</h2> <div>Content in section 2.</div> </section> <!-- Expanded on page load due to attribute: --> <section expanded> <h2>Section 3</h2> <div>Content in section 3.</div> </section> </bento-accordion> <script> (async () => { const accordion = document.querySelector('#my-accordion'); await customElements.whenDefined('bento-accordion'); const api = await accordion.getApi(); // programatically expand all sections api.expand(); // programatically collapse all sections api.collapse(); })(); </script>
</body>
操作
toggle()
toggle
操作切换 bento-accordion
部分的 expanded
和 collapsed
状态。当不带任何参数调用时,它会切换手风琴的所有部分。要指定特定部分,请添加 section
参数,并使用其对应的 id
作为值。
<bento-accordion id="myAccordion">
<section id="section1">
<h2>Section 1</h2>
<div>Bunch of awesome content</div>
</section>
<section>
<h2>Section 2</h2>
<div>Bunch of awesome content</div>
</section>
<section>
<h2>Section 3</h2>
<div>Bunch of awesome content</div>
</section>
</bento-accordion>
<button id="button1">Toggle All Sections</button>
<button id="button2">Toggle Section 1</button>
<script>
(async () => {
const accordion = document.querySelector('#myAccordion');
await customElements.whenDefined('bento-accordion');
const api = await accordion.getApi();
// set up button actions
document.querySelector('#button1').onclick = () => {
api.toggle();
};
document.querySelector('#button2').onclick = () => {
api.toggle('section1');
};
})();
</script>
expand()
expand
操作展开 bento-accordion
的部分。如果某个部分已展开,则它保持展开状态。当不带任何参数调用时,它会展开手风琴的所有部分。要指定一个部分,请添加 section
参数,并使用其对应的 id
作为值。
<bento-accordion id="myAccordion">
<section id="section1">
<h2>Section 1</h2>
<div>Bunch of awesome content</div>
</section>
<section>
<h2>Section 2</h2>
<div>Bunch of awesome content</div>
</section>
<section>
<h2>Section 3</h2>
<div>Bunch of awesome content</div>
</section>
</bento-accordion>
<button id="button1">Expand All Sections</button>
<button id="button2">Expand Section 1</button>
<script>
(async () => {
const accordion = document.querySelector('#myAccordion');
await customElements.whenDefined('bento-accordion');
const api = await accordion.getApi();
// set up button actions
document.querySelector('#button1').onclick = () => {
api.expand();
};
document.querySelector('#button2').onclick = () => {
api.expand('section1');
};
})();
</script>
collapse()
collapse
操作会折叠 bento-accordion
的部分。如果某个部分已经折叠,则它将保持折叠状态。当不带任何参数调用时,它会折叠手风琴的所有部分。要指定某个部分,请添加 section
参数,并使用其对应的 id
作为值。
<bento-accordion id="myAccordion">
<section id="section1">
<h2>Section 1</h2>
<div>Bunch of awesome content</div>
</section>
<section>
<h2>Section 2</h2>
<div>Bunch of awesome content</div>
</section>
<section>
<h2>Section 3</h2>
<div>Bunch of awesome content</div>
</section>
</bento-accordion>
<button id="button1">Collapse All Sections</button>
<button id="button2">Collapse Section 1</button>
<script>
(async () => {
const accordion = document.querySelector('#myAccordion');
await customElements.whenDefined('bento-accordion');
const api = await accordion.getApi();
// set up button actions
document.querySelector('#button1').onclick = () => {
api.collapse();
};
document.querySelector('#button2').onclick = () => {
api.collapse('section1');
};
})();
</script>
事件
bento-accordion
API 允许您注册并响应以下事件
expand
当手风琴部分展开时触发此事件,并从展开的部分派发。
请参阅以下示例。
collapse
当手风琴部分折叠时触发此事件,并从折叠的部分派发。
在以下示例中,section 1
侦听 expand
事件,并在展开时展开 section 2
。section 2
侦听 collapse
事件,并在折叠时折叠 section 1
。
请参阅以下示例。
事件示例
<bento-accordion id="eventsAccordion" animate>
<section id="section1">
<h2>Section 1</h2>
<div>Puppies are cute.</div>
</section>
<section id="section2">
<h2>Section 2</h2>
<div>Kittens are furry.</div>
</section>
</bento-accordion>
<script>
(async () => {
const accordion = document.querySelector('#eventsAccordion');
await customElements.whenDefined('bento-accordion');
const api = await accordion.getApi();
// when section 1 expands, section 2 also expands
// when section 2 collapses, section 1 also collapses
const section1 = document.querySelector('#section1');
const section2 = document.querySelector('#section2');
section1.addEventListener('expand', () => {
api.expand('section2');
});
section2.addEventListener('collapse', () => {
api.collapse('section1');
});
})();
</script>
布局和样式
每个 Bento 组件都有一个小 CSS 库,您必须包含它以保证在没有 内容偏移 的情况下正确加载。由于基于顺序的特异性,您必须手动确保在任何自定义样式之前包含样式表。
<link
rel="stylesheet"
type="text/css"
href="https://cdn.ampproject.org/v0/bento-accordion-1.0.css"
/>
或者,您还可以使轻量级预升级样式内联可用
<style>
bento-accordion {
display: block;
contain: layout;
}
bento-accordion,
bento-accordion > section,
bento-accordion > section > :first-child {
margin: 0;
}
bento-accordion > section > * {
display: block;
float: none;
overflow: hidden; /* clearfix */
position: relative;
}
@media (min-width: 1px) {
:where(bento-accordion > section) > :first-child {
cursor: pointer;
background-color: #efefef;
padding-right: 20px;
border: 1px solid #dfdfdf;
}
}
.i-amphtml-accordion-header {
cursor: pointer;
background-color: #efefef;
padding-right: 20px;
border: 1px solid #dfdfdf;
}
bento-accordion
> section:not([expanded])
> :last-child:not(.i-amphtml-animating),
bento-accordion
> section:not([expanded])
> :last-child:not(.i-amphtml-animating)
* {
display: none !important;
}
</style>
属性
animate
在 <bento-accordion>
中包含 animate
属性,以便在内容展开时添加“向下滚动”动画,在折叠时添加“向上滚动”动画。
此属性可以根据 媒体查询 进行配置。
<bento-accordion animate>
<section>
<h2>Section 1</h2>
<div>Content in section 1.</div>
</section>
<section>
<h2>Section 2</h2>
<div>Content in section 2.</div>
</section>
<section>
<h2>Section 3</h2>
<div>Content in section 2.</div>
</section>
</bento-accordion>
expanded
将 expanded
属性应用到嵌套的 <section>
,以便在页面加载时展开该部分。
<bento-accordion>
<section id="section1">
<h2>Section 1</h2>
<div>Bunch of awesome content</div>
</section>
<section id="section2">
<h2>Section 2</h2>
<div>Bunch of awesome content</div>
</section>
<section id="section3" expanded>
<h2>Section 3</h2>
<div>Bunch of awesome expanded content</div>
</section>
</bento-accordion>
expand-single-section
通过将 expand-single-section
属性应用到 <bento-accordion>
元素,一次只允许展开一个部分。这意味着,如果用户点击折叠的 <section>
,它将展开并折叠其他展开的 <section>
。
<bento-accordion expand-single-section>
<section>
<h2>Section 1</h2>
<div>Content in section 1.</div>
</section>
<section>
<h2>Section 2</h2>
<div>Content in section 2.</div>
</section>
<section>
<h2>Section 3</h2>
<img
src="https://source.unsplash.com/random/320x256"
width="320"
height="256"
/>
</section>
</bento-accordion>
样式
您可以使用 bento-accordion
元素选择器自由设置手风琴的样式。
为 amp-accordion 设置样式时,请记住以下几点
bento-accordion
元素始终为display: block
。float
无法为<section>
、标题或内容元素设置样式。- 展开的部分会将
expanded
属性应用于<section>
元素。 - 内容元素使用
overflow: hidden
进行清除修复,因此无法有滚动条。 <bento-accordion>
、<section>
、标题和内容元素的边距设置为0
,但可以在自定义样式中覆盖。- 标题和内容元素都是
position: relative
。
Preact/React 组件
通过 npm 导入
npm install @bentoproject/accordion
示例
import React from 'react'; import { BentoAccordion, BentoAccordionSection, BentoAccordionHeader, BentoAccordionContent } from '@bentoproject/accordion/react'; import '@bentoproject/accordion/styles.css'; function App() { return ( <BentoAccordion> <BentoAccordionSection key={1}> <BentoAccordionHeader> <h1>Section 1</h1> </BentoAccordionHeader> <BentoAccordionContent>Content 1</BentoAccordionContent> </BentoAccordionSection> <BentoAccordionSection key={2}> <BentoAccordionHeader> <h1>Section 2</h1> </BentoAccordionHeader> <BentoAccordionContent>Content 2</BentoAccordionContent> </BentoAccordionSection> <BentoAccordionSection key={3}> <BentoAccordionHeader> <h1>Section 3</h1> </BentoAccordionHeader> <BentoAccordionContent>Content 3</BentoAccordionContent> </BentoAccordionSection> </BentoAccordion> ); }
交互性和 API 使用
Bento 组件通过其 API 具有很强的交互性。可以通过传递 ref
来访问 BentoAccordion
组件 API
import React, {createRef} from 'react';
const ref = createRef();
function App() {
return (
<BentoAccordion ref={ref}>
<BentoAccordionSection id="section1" key={1}>
<BentoAccordionHeader>
<h1>Section 1</h1>
</BentoAccordionHeader>
<BentoAccordionContent>Content 1</BentoAccordionContent>
</BentoAccordionSection>
<BentoAccordionSection id="section2" key={2}>
<BentoAccordionHeader>
<h1>Section 2</h1>
</BentoAccordionHeader>
<BentoAccordionContent>Content 2</BentoAccordionContent>
</BentoAccordionSection>
<BentoAccordionSection id="section3" key={3}>
<BentoAccordionHeader>
<h1>Section 3</h1>
</BentoAccordionHeader>
<BentoAccordionContent>Content 3</BentoAccordionContent>
</BentoAccordionSection>
</BentoAccordion>
);
}
操作
BentoAccordion
API 允许您执行以下操作
toggle()
toggle
操作切换 bento-accordion
部分的 expanded
和 collapsed
状态。当不带任何参数调用时,它会切换手风琴的所有部分。要指定特定部分,请添加 section
参数,并使用其对应的 id
作为值。
ref.current.toggle();
ref.current.toggle('section1');
expand()
expand
操作展开 bento-accordion
的部分。如果某个部分已展开,则它保持展开状态。当不带任何参数调用时,它会展开手风琴的所有部分。要指定一个部分,请添加 section
参数,并使用其对应的 id
作为值。
ref.current.expand();
ref.current.expand('section1');
collapse()
collapse
操作会折叠 bento-accordion
的部分。如果某个部分已经折叠,则它将保持折叠状态。当不带任何参数调用时,它会折叠手风琴的所有部分。要指定某个部分,请添加 section
参数,并使用其对应的 id
作为值。
ref.current.collapse();
ref.current.collapse('section1');
事件
Bento Accordion API 允许您响应以下事件
onExpandStateChange
当手风琴部分展开或折叠时,此事件会在部分中触发,并从展开的部分分派。
有关示例,请参见下面的 示例。
onCollapse
当手风琴部分折叠时,此事件会在部分中触发,并从折叠的部分分派。
在以下示例中,section 1
侦听 expand
事件,并在展开时展开 section 2
。section 2
侦听 collapse
事件,并在折叠时折叠 section 1
。
有关示例,请参见下面的 示例。
事件示例
import React, {createRef} from 'react'; import { BentoAccordion, BentoAccordionSection, BentoAccordionHeader, BentoAccordionContent } from '@bentoproject/accordion/react'; import '@bentoproject/accordion/styles.css'; function App() { const ref = createRef(); return ( <BentoAccordion ref={ref}> <BentoAccordionSection id="section1" key={1} onExpandStateChange={(expanded) => { alert(expanded ? 'section1 expanded' : 'section1 collapsed'); }} > <BentoAccordionHeader> <h1>Section 1</h1> </BentoAccordionHeader> <BentoAccordionContent>Content 1</BentoAccordionContent> </BentoAccordionSection> <BentoAccordionSection id="section2" key={2} onExpandStateChange={(expanded) => { alert(expanded ? 'section2 expanded' : 'section2 collapsed'); }} > <BentoAccordionHeader> <h1>Section 2</h1> </BentoAccordionHeader> <BentoAccordionContent>Content 2</BentoAccordionContent> </BentoAccordionSection> <BentoAccordionSection id="section3" key={3} onExpandStateChange={(expanded) => { alert(expanded ? 'section3 expanded' : 'section3 collapsed'); }} > <BentoAccordionHeader> <h1>Section 3</h1> </BentoAccordionHeader> <BentoAccordionContent>Content 3</BentoAccordionContent> </BentoAccordionSection> </BentoAccordion> ) }
布局和样式
容器类型
BentoAccordion
组件具有已定义的布局大小类型。为确保组件正确渲染,请务必通过所需的 CSS 布局(例如使用 height
、width
、aspect-ratio
或其他此类属性定义的布局)将大小应用于组件及其直接子级。这些可以内联应用
<BentoAccordion style={{width: 300, height: 100}}>...</BentoAccordion>
或通过 className
<BentoAccordion className="custom-styles">...</BentoAccordion>
.custom-styles {
background-color: red;
}
属性
BentoAccordion
animate
如果为 true,则在每个部分的展开和折叠期间使用“向下滚动”/“向上滚动”动画。
默认值:false
expandSingleSection
如果为 true,则展开 1 个部分将自动折叠所有其他部分。
默认值:false
BentoAccordionSection
animate
如果为 true,则在展开和折叠部分期间使用“向下滚动”/“向上滚动”动画。
默认值:false
expanded
如果为 true,则展开部分。
默认值:false
onExpandStateChange
(expanded: boolean): void
用于侦听展开状态更改的回调。以布尔标志作为参数,指示部分是否刚刚展开(false
表示已折叠)
BentoAccordionHeader
通用属性
此组件支持 React 和 Preact 组件的通用属性。
BentoAccordionHeader 暂不支持任何自定义属性
BentoAccordionContent
通用属性
此组件支持 React 和 Preact 组件的通用属性。
BentoAccordionContent 暂不支持任何自定义属性