gpt4 book ai didi

javascript - 在别处单击时关闭 Material UI 组件

转载 作者:行者123 更新时间:2023-11-29 14:44:09 24 4
gpt4 key购买 nike

我已经使用 Material UI 默认组件构建了一个组件。这是一个菜单。一旦用户单击菜单外的任何位置,我想关闭此菜单。

我该怎么做?图标菜单就是这样做的。当您单击 body 上的其他任何地方时,菜单会关闭,但 Menu 组件不会关闭。在查看图标菜单代码后,我注意到它如何通过一些更改来呈现菜单组件,但无法找到在单击外部主体时触发关闭的功能。

下面是图标菜单的代码

const React = require('react');
const ReactDOM = require('react-dom');
const ReactTransitionGroup = require('react-addons-transition-group');
const ClickAwayable = require('../mixins/click-awayable');
const StylePropable = require('../mixins/style-propable');
const Events = require('../utils/events');
const PropTypes = require('../utils/prop-types');
const Menu = require('../menus/menu');
const DefaultRawTheme = require('../styles/raw-themes/light-raw-theme');
const ThemeManager = require('../styles/theme-manager');

const IconMenu = React.createClass({

mixins: [StylePropable, ClickAwayable],

contextTypes: {
muiTheme: React.PropTypes.object,
},

propTypes: {
closeOnItemTouchTap: React.PropTypes.bool,
iconButtonElement: React.PropTypes.element.isRequired,
iconStyle: React.PropTypes.object,
openDirection: PropTypes.corners,
onItemTouchTap: React.PropTypes.func,
onKeyboardFocus: React.PropTypes.func,
onMouseDown: React.PropTypes.func,
onMouseLeave: React.PropTypes.func,
onMouseEnter: React.PropTypes.func,
onMouseUp: React.PropTypes.func,
onTouchTap: React.PropTypes.func,
menuStyle: React.PropTypes.object,
style: React.PropTypes.object,
touchTapCloseDelay: React.PropTypes.number,
},

getDefaultProps() {
return {
closeOnItemTouchTap: true,
openDirection: 'bottom-left',
onItemTouchTap: () => {},
onKeyboardFocus: () => {},
onMouseDown: () => {},
onMouseLeave: () => {},
onMouseEnter: () => {},
onMouseUp: () => {},
onTouchTap: () => {},
touchTapCloseDelay: 200,
};
},

//for passing default theme context to children
childContextTypes: {
muiTheme: React.PropTypes.object,
},

getChildContext () {
return {
muiTheme: this.state.muiTheme,
};
},

getInitialState () {
return {
muiTheme: this.context.muiTheme ? this.context.muiTheme : ThemeManager.getMuiTheme(DefaultRawTheme),
iconButtonRef: this.props.iconButtonElement.props.ref || 'iconButton',
menuInitiallyKeyboardFocused: false,
open: false,
};
},

//to update theme inside state whenever a new theme is passed down
//from the parent / owner using context
componentWillReceiveProps (nextProps, nextContext) {
let newMuiTheme = nextContext.muiTheme ? nextContext.muiTheme : this.state.muiTheme;
this.setState({muiTheme: newMuiTheme});
},

componentWillUnmount() {
if (this._timeout) clearTimeout(this._timeout);
},

componentClickAway() {
this.close();
},

render() {
let {
className,
closeOnItemTouchTap,
iconButtonElement,
iconStyle,
openDirection,
onItemTouchTap,
onKeyboardFocus,
onMouseDown,
onMouseLeave,
onMouseEnter,
onMouseUp,
onTouchTap,
menuStyle,
style,
...other,
} = this.props;

let open = this.state.open;
let openDown = openDirection.split('-')[0] === 'bottom';
let openLeft = openDirection.split('-')[1] === 'left';

let styles = {
root: {
display: 'inline-block',
position: 'relative',
},

menu: {
top: openDown ? 12 : null,
bottom: !openDown ? 12 : null,
left: !openLeft ? 12 : null,
right: openLeft ? 12 : null,
},
};

let mergedRootStyles = this.prepareStyles(styles.root, style);
let mergedMenuStyles = this.mergeStyles(styles.menu, menuStyle);

let iconButton = React.cloneElement(iconButtonElement, {
onKeyboardFocus: this.props.onKeyboardFocus,
iconStyle: this.mergeStyles(iconStyle, iconButtonElement.props.iconStyle),
onTouchTap: (e) => {
this.open(Events.isKeyboard(e));
if (iconButtonElement.props.onTouchTap) iconButtonElement.props.onTouchTap(e);
},
ref: this.state.iconButtonRef,
});

let menu = open ? (
<Menu
{...other}
animated={true}
initiallyKeyboardFocused={this.state.menuInitiallyKeyboardFocused}
onEscKeyDown={this._handleMenuEscKeyDown}
onItemTouchTap={this._handleItemTouchTap}
openDirection={openDirection}
style={mergedMenuStyles}>
{this.props.children}
</Menu>
) : null;

return (
<div
className={className}
onMouseDown={onMouseDown}
onMouseLeave={onMouseLeave}
onMouseEnter={onMouseEnter}
onMouseUp={onMouseUp}
onTouchTap={onTouchTap}
style={mergedRootStyles}>
{iconButton}
<ReactTransitionGroup>{menu}</ReactTransitionGroup>
</div>
);
},

isOpen() {
return this.state.open;
},

close(isKeyboard) {
if (this.state.open) {
this.setState({open: false}, () => {
//Set focus on the icon button when the menu close
if (isKeyboard) {
let iconButton = this.refs[this.state.iconButtonRef];
ReactDOM.findDOMNode(iconButton).focus();
iconButton.setKeyboardFocus();
}
});
}
},

open(menuInitiallyKeyboardFocused) {
if (!this.state.open) {
this.setState({
open: true,
menuInitiallyKeyboardFocused: menuInitiallyKeyboardFocused,
});
}
},

_handleItemTouchTap(e, child) {

if (this.props.closeOnItemTouchTap) {
let isKeyboard = Events.isKeyboard(e);

this._timeout = setTimeout(() => {
this.close(isKeyboard);
}, this.props.touchTapCloseDelay);
}

this.props.onItemTouchTap(e, child);
},

_handleMenuEscKeyDown() {
this.close(true);
},

});

module.exports = IconMenu;

最佳答案

此行为由 ClickAwayable 混合宏给出,您可以找到源代码 here

只需在您的自定义组件中导入(或要求)它并添加一个 componentClickAway 方法来触发关闭您的菜单。

const ClickAwayable = require('material-ui/lib/mixins/click-awayable')

const CustomMenu = React.createClass({

mixins: [ClickAwayable],

componentClickAway () {
// close your menu
}

})

关于javascript - 在别处单击时关闭 Material UI 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34698519/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com