如何在按钮单击上切换下拉菜单并在外部单击上关闭?

时间:2019-07-20 09:51:33

标签: javascript html reactjs

我有一个下拉菜单,该下拉菜单通过单击按钮打开,而在外部单击时关闭。

此功能可切换下拉菜单:

toggleAllCategories = () => {
  this.setState({ isOpenAllCategories: !this.state.isOpenAllCategories });
};

这意味着点击按钮,您应该打开和关闭下拉菜单。

但是与此同时,我使用react-refs实现了在下拉菜单主体之外单击---> close下拉菜单。

那是臭虫-复制:

第1步:点击“所有类别” btn

结果:下拉列表已打开

第2步:再次点击“所有类别” btn-用户想关闭下拉菜单

结果:结果下拉列表打开。

  1. 点击“所有类别” btn(状态已更改为isOpenAllCategories = true)

这里是问题-> 2.再次单击“所有类别” btn

  • 第一个称为handleOutsideClick()函数,该函数设置isOpenAllCategories on false

  • 然后称为toggleAllCategories(),它根据当前值isOpenAllCategories: !this.state.isOpenAllCategories的相反而改变状态,也就是说true cus handleOutsideClick()已经改变了false的状态

如何在单击按钮时切换下拉菜单并在单击外部按钮时关闭?

“所有类别”下拉列表组件:

class AllCategories extends Component {

  componentDidMount() {
    document.addEventListener('mousedown', (e) => this.handleClickOutside(e));
  }

  componentWillUnmount() {
    document.removeEventListener('mousedown', (e) => this.handleClickOutside(e));
  }

  setWrapperRef(node) {
    this.wrapperRef = node;
  }

  handleClickOutside = (event) => {
    if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
      this.props.closeAllCategories();
    }
  };

  render() {
    return (
      <div className="all-categories-wrapper">
        <div className="all-categories" ref={(node) => this.setWrapperRef(node)}>
          <ul className="all-categories-list">
            <li className="all-categories-list-item">All Categories</li>
            {this.state.allCategories.map((category) => (
              <li
                className={`all-categories-list-item ${
                  category.selected ? 'all-categories-list-item-active' : ''
                }`}
              >
                {category.name}
              </li>
            ))}
          </ul>
        </div>
      </div>
    );
  }
}

所有类别按钮组件:

export default ({ toggleAllCategories, className }) => (
  <div className="category" onClick={() => toggleAllCategories()} role="button">
    <div className={`category-button-wrapper ${className}`}>
      <button className="category-button">
        Sports <span className="category-button-slash">/</span> Football
      </button>
      <div className="category-icon-box">
        <span className="category-icon">
          <i className="material-icons md-30 md-white">expand_more</i>
        </span>
      </div>
    </div>
  </div>
);

1 个答案:

答案 0 :(得分:1)

由于组件功能中 this 的范围,代码无法正常工作。您必须将函数绑定到组件的构造函数中。或将功能更改为ES6即可解决问题

<head>
  <meta charset="utf-8">
  <title>Home - akiro</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link href="https://fonts.googleapis.com/css?family=Oswald&display=swap" rel="stylesheet">
  <link href="https://fonts.googleapis.com/css?family=Merriweather&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="style.css" type="text/css">
</head>