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