demand

Recently, the react project needs to write a customized menu by hand, which is different from the MENU of ANTD. Click the first-level menu and the second-level and third-level menus are displayed, similar to those of Drawer. The menu styles are customized and displayed in a Drawer.

The difficulties in

The difficulty is that Drawer pops up when you click the level-1 menu. Click DOM except Drawer and level-1 menu items, and Drawer collapses.

The problem

React has its own event handling mechanism to improve performance. This means that the listener function is not bound to the Dom. To prevent the react event from bubblinge. topPropagation(), the function does not prevent native events from bubbling. if you click on a Drawer, the function collapses. Disable native event bubbling e.n ativeEvent. StopPropagation (), the React of monitoring function is invoked, characterized by click on the Drawer outside the dom, the Drawer won’t fold. None of this is what we want.

The solution

The correct posture is to determine whether the event. Target object is the target object or contains the target object or is contained by the target object to determine whether to fire the event

  componentDidMount() {
    document.addEventListener('click'.this.hideDrawer);
  }

  componentWillUnmount() {
    document.removeEventListener('click'.this.hideDrawer);
  }

  hideDrawer = e= > {
    const { closeDrawer } = this.props;
    // Find dom level 1 menus that do not need to be closed
    const tabContent = document.querySelectorAll('.ant-menu-submenu-vertical');
   // Find the DOM Drawer that does not need to be closed
    const drawerContent = document.querySelector('#menuDrawer');
   // Check whether the currently clicked DOM object is contained in the target DOM
    const isHave = Array.from(tabContent).some(item= > item.contains(e.target));
   If the Drawer is not included, the Drawer is closed and the other business logic is removed
    if(tabContent ! = =null&&! (isHave || drawerContent.contains(e.target))) { closeDrawer(); }};Copy the code