Bento

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 手风琴在用户停留在您的域名时保留每个部分的折叠或展开状态。

将 bento-accordion 用作 Web 组件或 React 函数组件

↓ Web 组件 ↓ React / Preact

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 部分的 expandedcollapsed 状态。当不带任何参数调用时,它会切换手风琴的所有部分。要指定特定部分,请添加 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 2section 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 部分的 expandedcollapsed 状态。当不带任何参数调用时,它会切换手风琴的所有部分。要指定特定部分,请添加 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 2section 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 布局(例如使用 heightwidthaspect-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 暂不支持任何自定义属性

更多详情