当单击发生在下拉组件之外时,我想关闭下拉菜单。
我怎么做?
当单击发生在下拉组件之外时,我想关闭下拉菜单。
我怎么做?
使用生命周期方法向文档添加和删除事件侦听器。
React.createClass({
handleClick: function (e) {
if (this.getDOMNode().contains(e.target)) {
return;
}
},
componentWillMount: function () {
document.addEventListener('click', this.handleClick, false);
},
componentWillUnmount: function () {
document.removeEventListener('click', this.handleClick, false);
}
});
查看此组件的第 48-54 行:https : //github.com/i-like-robots/react-tube-tracker/blob/91dc0129a1f6077bef57ea4ad9a860be0c600e9d/app/component/tube-tracker.jsx#L48-54
在我添加的元素中mousedown
,mouseup
像这样:
onMouseDown={this.props.onMouseDown} onMouseUp={this.props.onMouseUp}
然后在父母中我这样做:
componentDidMount: function () {
window.addEventListener('mousedown', this.pageClick, false);
},
pageClick: function (e) {
if (this.mouseIsDownOnCalendar) {
return;
}
this.setState({
showCal: false
});
},
mouseDownHandler: function () {
this.mouseIsDownOnCalendar = true;
},
mouseUpHandler: function () {
this.mouseIsDownOnCalendar = false;
}
这showCal
是一个布尔值,true
在我的情况下显示日历并false
隐藏它。
查看事件的目标,如果事件直接在组件或该组件的子组件上,则单击在内部。否则它在外面。
React.createClass({
clickDocument: function(e) {
var component = React.findDOMNode(this.refs.component);
if (e.target == component || $(component).has(e.target).length) {
// Inside of the component.
} else {
// Outside of the component.
}
},
componentDidMount: function() {
$(document).bind('click', this.clickDocument);
},
componentWillUnmount: function() {
$(document).unbind('click', this.clickDocument);
},
render: function() {
return (
<div ref='component'>
...
</div>
)
}
});
如果要在许多组件中使用它,最好使用 mixin:
var ClickMixin = {
_clickDocument: function (e) {
var component = React.findDOMNode(this.refs.component);
if (e.target == component || $(component).has(e.target).length) {
this.clickInside(e);
} else {
this.clickOutside(e);
}
},
componentDidMount: function () {
$(document).bind('click', this._clickDocument);
},
componentWillUnmount: function () {
$(document).unbind('click', this._clickDocument);
},
}
请参阅此处的示例:https : //jsfiddle.net/0Lshs7mg/1/
对于您的特定用例,当前接受的答案有点过度设计。如果您想监听用户何时从下拉列表中单击,只需使用一个<select>
组件作为父元素并onBlur
为其附加一个处理程序。
这种方法的唯一缺点是它假设用户已经保持对元素的关注,并且它依赖于表单控件(如果您考虑到tab
键也聚焦和模糊元素,这可能是也可能不是您想要的) - 但这些缺点实际上只是更复杂用例的限制,在这种情况下,可能需要更复杂的解决方案。
var Dropdown = React.createClass({
handleBlur: function(e) {
// do something when user clicks outside of this element
},
render: function() {
return (
<select onBlur={this.handleBlur}>
...
</select>
);
}
});