如何通过单击组件中的图标来滚动和展开手风琴?

Posted

技术标签:

【中文标题】如何通过单击组件中的图标来滚动和展开手风琴?【英文标题】:How to scroll and expand an Accordion by onClick on an icon from a component? 【发布时间】:2020-12-11 02:04:26 【问题描述】:

我有一个组件 MainContent 及其子组件 AddMockMainContent 中有一个表格,其中显示了一些项目列表。它对每一行都有特定的操作,例如视图和编辑,这些操作由图标通过语义 UI 反应呈现。通过单击每个图标,我需要向上滚动并展开手风琴。手风琴在AddMock

// AddMock.js
const AddMock = () => 
  return (
    <div className="row">
      <Accordion style= paddingLeft: "32px" >
        <Card className="collapseStyle">
          <Card.Header>
            <Accordion.Toggle as=Button variant="link" eventKey="0">
              Add Mock
            </Accordion.Toggle>
          </Card.Header>
          <Accordion.Collapse eventKey="0">
            <Card.Body>
              <Container className="mockbody">
                <Header as="h3">Hierarchy</Header>
                <TabContent />
              </Container>
            </Card.Body>
          </Accordion.Collapse>
        </Card>
      </Accordion>
    </div>
  );
;

下面是 MainContent.js

const MainContent = () => 
  
  return (
    <div>
      <AddMock />
      <div className="container-fluid">
        <div className="row">
          <div className="col-md-12">
            <div className="card">
              <div className="card-header card-header-info">
                <h4 className="card-title ">MOCK</h4>
              </div>
              <div className="card-body">
                <form>
                  loading ? (
                    <div className="table-responsive">
                      <table className="table">
                        <thead>
                          <tr>
                            <th>AppName</th>
                            <th>Parent_App</th>
                            <th>Created_Date</th>
                            <th>Req_Path</th>
                            <th>Resp_Code</th>
                            <th>Resp_Content_Type</th>
                            <th>Resp_Delay</th>
                            <th>Action</th>
                          </tr>
                        </thead>
                        <tbody>
                          data.map((routes, index) => 
                            return routes.map(contents, index);
                          )
                        </tbody>
                      </table>
                    </div>
                  ) : (
                    <Spinner
                      animation="border"
                      style= marginLeft: "620px" 
                    />
                  )
                </form>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
;

是否可以使用 window.scrollTo() 或任何其他更好的方式在 react 中实现这一点?

【问题讨论】:

我认为你可以在这种情况下使用 refs。看看这个:***.com/questions/43441856/… @kubilaysalih:你能举个例子说明我如何在我的情况下添加这个吗? 这里的例子:codesandbox.io/s/… 也检查这个库。你可以使用带有流畅动画的参考版本github.com/ganderzz/react-scroll-to 【参考方案1】:

使用参考

首先,我们可以有一个状态来保持活动 Accordion 的 eventKey

const [activeKey, setActiveKey] = useState("");

之后,我们将ref 用于我们的 React-Bootstrap Accordion 组件。稍后我们需要使用Forwarded Refs 至少为 Accordion 组件的最顶层 DOM 元素分配一个 ref,以便我们可以滚动到它。

至于图标,看看它的onClick 事件,这只是将activeKey 设置为"0",它与您的Accordion.Collapse 组件的eventKey 映射。这将作为其“扩张”的触发点。

// we are going to need a ref to the Accordion element go get its position/use the scrollIntoView function
const accordElem = useRef(null);

const handleClickEdit = () => 
  setActiveKey("0"); // "0" here is as defined in your Accordion.Collapse eventKey
  accordElem.current.scrollIntoView(
    behavior: "smooth",
    block: "end",
    inline: "nearest"
  ); // initiate scroll to the "AddMock" Accordion component
;

return (
  <div>
    <AddMock
      activeKey=activeKey
      setActiveKey=setActiveKey
      ref=accordElem
    />

    ...

    <Icon
      name="pencil"
      size="huge"
      style= cursor: "pointer" 
      onClick=() => handleClickEdit("0")
    />

对于滚动,我们可以使用https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView。除此之外,当然还有其他的替代品如scrollTo

最后,这是我们的 Accordion 组件在转发 ref 和利用从父状态获取的 activeKey 属性时的样子:

const AddMock = React.forwardRef((props, ref) => 
  // optional re-toggling of expanded accordion
  function handleClickToggle(eventKey) 
    if (eventKey === props.activeKey) 
      props.setActiveKey("");
     else 
      props.setActiveKey(eventKey);
    
  

  return (
    <div className="row" ref=ref>
      <Accordion style= paddingLeft: "32px"  activeKey=props.activeKey>
        <Card className="collapseStyle">
          <Card.Header>
            <Accordion.Toggle
              as=Button
              variant="link"
              eventKey="0"
              onClick=() => handleClickToggle("0")
            >
              Add Mock
            </Accordion.Toggle>
          </Card.Header>
          <Accordion.Collapse eventKey="0">
            <Card.Body>
              ...

代码沙盒:https://codesandbox.io/s/react-semantic-ui-react-bootstrap-3ndyl?file=/src/App.js:2444-3230

【讨论】:

感谢您的帮助,感谢您的努力 :)

以上是关于如何通过单击组件中的图标来滚动和展开手风琴?的主要内容,如果未能解决你的问题,请参考以下文章

React - Material-UI Accordion:如何使标题居中并展开图标

在 Knockout foreach 循环中引导 4 手风琴,在展开/折叠问题时更改图标

如何一次打开所有 Bootstrap 手风琴标签

AngularJS / ui-bootstrap 手风琴 - 单击时滚动到活动(打开)手风琴的顶部

单击时手风琴滚动到顶部?

滚动 - 单击时无法滚动固定侧边栏中的自定义滚动