📜  一次打开一个下拉菜单 (1)

📅  最后修改于: 2023-12-03 15:21:26.633000             🧑  作者: Mango

一次打开一个下拉菜单

在编写 UI 界面时,下拉菜单是经常使用的一个控件。在用户点击下拉菜单时,通常会弹出一个菜单列表供用户选择。

本文将介绍如何实现一次只打开一个下拉菜单的功能,即当用户点击一个下拉菜单时,其他所有下拉菜单都将关闭,只打开当前点击的下拉菜单。

实现思路

实现此功能的思路比较简单,即在点击下拉菜单时,遍历所有下拉菜单,将其它下拉菜单关闭,只打开当前点击的下拉菜单。

为了更好地实现此功能,我们可以将每个下拉菜单封装成一个组件,并将每个组件都设置一个唯一的 ID。当用户点击某个下拉菜单时,组件将向父组件发送一个事件,通知父组件关闭其它所有下拉菜单,并打开当前点击的下拉菜单。

父组件接收到事件后,遍历所有下拉菜单组件,将其它组件关闭。

以下为组件结构图:

Parent Component
└─ Dropdown Component 1
└─ Dropdown Component 2
└─ ...
代码实现

我们以 React 为例来实现这个功能。

首先,我们创建一个父组件 Parent,用于包含所有的下拉菜单组件:

import React, { useState } from 'react';
import Dropdown from './Dropdown';

function Parent() {
  const [activeId, setActiveId] = useState(null);

  function handleDropdownClick(id) {
    setActiveId(id);
  }

  return (
    <div>
      <Dropdown id="dropdown1" active={activeId === 'dropdown1'} onClick={() => handleDropdownClick('dropdown1')} />
      <Dropdown id="dropdown2" active={activeId === 'dropdown2'} onClick={() => handleDropdownClick('dropdown2')} />
      {/* ... */}
    </div>
  );
}

export default Parent;

从上面的代码可以看出,我们在 Parent 组件中定义了一个 activeId 状态来记录当前激活的下拉菜单组件的 ID。接着,我们定义了一个 handleDropdownClick 函数来处理下拉菜单的点击事件,并将点击的菜单组件 ID 赋值给 activeId 状态。

接下来,我们创建一个 Dropdown 子组件,用于显示下拉菜单:

import React, { forwardRef } from 'react';
import PropTypes from 'prop-types';

const Dropdown = forwardRef(({ id, active, onClick }, ref) => {
  return (
    <div
      ref={ref}
      className="dropdown"
      style={{
        display: active ? 'block' : 'none',
      }}
      onClick={onClick}
    >
      {/* 下拉菜单内容 */}
    </div>
  );
});

Dropdown.propTypes = {
  id: PropTypes.string.isRequired,
  active: PropTypes.bool.isRequired,
  onClick: PropTypes.func.isRequired,
};

export default Dropdown;

在上面的代码中,我们使用了 React Hooks 中的 forwardRef 函数将 Dropdown 组件包装一下。

我们的 Dropdown 组件接收了以下 3 个属性:

  • id:下拉菜单的唯一 ID
  • active:下拉菜单是否激活
  • onClick:下拉菜单点击事件

接着,在 return 中,我们根据 active 属性的值来判断下拉菜单是否显示。

下面是 Dropdown 组件的使用方式:

<Dropdown id="dropdown1" active={activeId === 'dropdown1'} onClick={() => handleDropdownClick('dropdown1')} />

最后,我们定义 handleDropdownClick 函数,用于遍历所有下拉菜单组件,将其它组件关闭:

function handleDropdownClick(id) {
  setActiveId(id);
  const dropdowns = document.querySelectorAll('.dropdown');

  dropdowns.forEach((dropdown) => {
    if (dropdown.id !== id) {
      dropdown.style.display = 'none';
    }
  });
}

我们可以在 handleDropdownClick 函数中使用 querySelectorAll 方法查询所有下拉菜单,并使用 forEach 方法遍历这些下拉菜单。如果下拉菜单的 ID 不等于当前点击的菜单组件 ID,则将其状态调整为不激活。

总结

通过以上实现,我们成功地实现了每次打开一个下拉菜单的功能。这种实现方式是比较简单且易懂的,适用于简单的应用场景。