簡體   English   中英

單擊下拉菜單外部時隱藏下拉菜單

[英]Hide dropdown menu upon clicking outside of it

我在 React 應用程序中實現的下拉菜單有問題。

下拉列表基於這篇文章: https : //blog.campvanilla.com/reactjs-dropdown-menus-b6e06ae3a8fe

打開和關閉下拉菜單可以正常工作,但是當我單擊菜單中的按鈕時,出現以下錯誤:

TypeError: Cannot read property 'contains' of null

回到博客,看到其他人在評論中也報告了同樣的錯誤:

好一個。 但只是最后一部分不起作用。 dropDownMenu 保持“空”

一種可能的解決方案是將current添加到以下代碼行:

原版

if (!this.dropdownMenu.contains(event.target)) {

修改的:

if (!this.dropdownMenu.current.contains(event.target)) {

我在 StackOverflow 上找到了一個類似的答案,其中另一個用戶遇到了下拉菜單的問題: Cannot read property 'addEventListener' of null on menu但我仍然無法找出錯誤。

內部頭文件.jsx

import React, { Component } from 'react';
import {Link, withRouter} from 'react-router-dom'
import logo from '../images/logo.svg'
import Settings from '../lotties/Settings'

class InnerHeader extends Component {
  constructor() {
  super();
    
  this.state = {
    showMenu: false,
    fade: false
  };
  
  this.showMenu = this.showMenu.bind(this);
  this.closeMenu = this.closeMenu.bind(this);
}


showMenu(event) {
  event.preventDefault();
  
  this.setState({ showMenu: true }, () => {
    document.addEventListener('click', this.closeMenu);
  });
}

closeMenu(event) {
  if (!this.dropdownMenu.current.contains(event.target)) {
    
    this.setState({ showMenu: false }, () => {
      document.removeEventListener('click', this.closeMenu);
    });  
    
  }
}
 
handleLogout = () => {
    localStorage.removeItem('authToken');
    this.setState({
      currentUser: null
    })
    this.props.history.push("/")
  }

render() {
    return (
        <>
        <div id="inner-header">
          <div className="logo">
            <Link to="/dashboard"><img src={logo} height="50px" alt="site logo" /></Link>
          </div>
          <div>
        <button 
          className="menu-button"
          onClick={this.showMenu}>
          <Settings/>
        </button>
        <br />
        {
          this.state.showMenu
          ? (
            <div
            className="drop-down fade-in"
            ref={(element) => {
              this.dropdownMenu = element;
            }}
            >
                <div className="center-it-menu">
                <Link to="/account">  Account </Link>
                <br />
                <Link to="/integrations"> Integrations </Link>
                <br />
                <Link to="/tutorials"> Tutorials </Link>
                <br />
                <Link to="/support"> Support </Link>
                <br />
                <button id="menu-alert" onClick={this.handleLogout}> Logout </button>
                </div>
              </div>
            )
            : (
              null
              )
            }
      </div>
        </div>
      </>
    )
  }
}

export default withRouter(InnerHeader)

由於我仍在學習編程,因此我不想依賴庫來完成這項任務,也不想只是 c&p 一個解決方案。 除了解決方案之外,我想知道是什么導致了這種情況以及如何解決它。 由於它是您在 google react 創建下拉菜單時顯示的第一篇文章之一,因此如果其他人試圖實現這一點,我希望他們有一個很好的答案。

我必須說,根本不需要所描述場景中的 ref 屬性。 要在菜單外部單擊時折疊菜單,您可以使用Element.closest()方法,該方法將向下遍歷 DOM 樹以在event.target祖先中查找className="menu"元素:

 const { Component } = React, { render } = ReactDOM class Card extends Component { constructor() { super(); this.state = { showMenu: false, }; this.showMenu = this.showMenu.bind(this); this.closeMenu = this.closeMenu.bind(this); } showMenu(event) { event.preventDefault(); this.setState({ showMenu: true }, () => { document.addEventListener('click', this.closeMenu); }); } closeMenu(event) { if (!event.target.closest('.menu')) { this.setState({ showMenu: false }, () => { document.removeEventListener('click', this.closeMenu); }); } } render() { return ( <div> <button onClick={this.showMenu}> Show menu </button> { this.state.showMenu ? ( <div className="menu" > <button> Menu item 1 </button> <button> Menu item 2 </button> <button> Menu item 3 </button> </div> ) : ( null ) } </div> ); } } render (<Card />, document.getElementById('root'))
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>

這是因為當您不單擊Button 時,此代碼不會執行並且不會啟動this.dropdownMenu因此它是Undefined 在這種情況下,您應該使用onChange事件並向其添加一個偵聽器,然后在該函數中執行您想要的任何操作。 願它會幫助你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM