Reactjs 如何侦听组件外部的单击事件
我想在下拉组件外单击时关闭下拉菜单Reactjs 如何侦听组件外部的单击事件,reactjs,Reactjs,我想在下拉组件外单击时关闭下拉菜单 如何做到这一点?使用生命周期方法向文档中添加和删除事件侦听器 React.createClass({ handleClick:函数(e){ if(this.getDOMNode().包含(e.target)){ 返回; } }, componentWillMount:函数(){ document.addEventListener('click',this.handleClick,false); }, componentWillUnmount:函数(){ doc
如何做到这一点?使用生命周期方法向文档中添加和删除事件侦听器
React.createClass({
handleClick:函数(e){
if(this.getDOMNode().包含(e.target)){
返回;
}
},
componentWillMount:函数(){
document.addEventListener('click',this.handleClick,false);
},
componentWillUnmount:函数(){
document.removeEventListener('click',this.handleClick,false);
}
});
查看此组件的第48-54行:查看事件的目标,如果事件直接位于组件或该组件的子组件上,则单击位于内部。否则它就在外面
React.createClass({
单击文档:功能(e){
var component=React.findDOMNode(此.refs.component);
if(e.target==component | |$(component).has(e.target.length){
//组件的内部。
}否则{
//组件外部。
}
},
componentDidMount:function(){
$(document.bind('click',this.clickDocument));
},
componentWillUnmount:function(){
$(文档).unbind('click',this.clickDocument));
},
render:function(){
返回(
...
)
}
});
如果要在许多组件中使用,则使用mixin会更好:
var ClickMixin={
_单击文档:功能(e){
var component=React.findDOMNode(此.refs.component);
if(e.target==component | |$(component).has(e.target.length){
点击此按钮。点击内部(e);
}否则{
点击外部(e);
}
},
componentDidMount:函数(){
$(文档).bind('单击',此。\ u单击文档);
},
componentWillUnmount:函数(){
$(文档)。解除绑定('单击',此。\ u单击文档);
},
}
请参见此处的示例:在我添加的元素中
mousedown
和mouseup
如下所示:
onMouseDown={this.props.onMouseDown}onMouseUp={this.props.onMouseUp}
然后在父级中,我执行以下操作:
componentDidMount:function(){
window.addEventListener('mousedown',this.pageClick,false);
},
页面点击:功能(e){
if(this.mouseIsDownOnCalendar){
返回;
}
这是我的国家({
肖卡尔:错
});
},
mouseDownHandler:函数(){
this.mouseIsDownOnCalendar=true;
},
鼠标句柄:函数(){
this.mouseIsDownOnCalendar=false;
}
showCal
是一个布尔值,当true
在我的例子中显示日历时,false
将其隐藏
.background
).target
)置于.background
元素之外,并具有更大的堆叠索引(z-index
).background
元素将被视为“在.target
元素之外”
。单击覆盖{
位置:固定;
左:0;
右:0;
排名:0;
底部:0;
z指数:1;
}
.目标{
位置:相对位置;
z指数:2;
}
- 以下是一个例子:
- 有关讨论的更多信息:
组件作为父元素,并向其附加onBlur
处理程序
这种方法唯一的缺点是,它假设用户已经保持对元素的关注,并且它依赖于表单控件(如果考虑到选项卡
键也会聚焦和模糊元素,那么表单控件可能是您想要的,也可能不是),但这些缺点实际上只是对更复杂用例的限制,在这种情况下,可能需要更复杂的解决方案
var Dropdown = React.createClass({
handleBlur: function(e) {
// do something when user clicks outside of this element
},
render: function() {
return (
<select onBlur={this.handleBlur}>
...
</select>
);
}
});
var Dropdown=React.createClass({
把手:功能(e){
//当用户在该元素之外单击时执行某些操作
},
render:function(){
返回(
...
);
}
});
我已经为源于组件外部的事件编写了一个通用事件处理程序
实现本身很简单:
- 安装组件时,事件处理程序会附加到
对象窗口
- 当事件发生时,组件将检查事件是否源自组件内部。如果没有,则会在目标组件上触发onOutsideEvent
- 卸载组件时,事件处理程序将被取消激活
从“React”导入React;
从“react dom”导入react dom;
/**
*@param{ReactClass}以定义`onOutsideEvent`处理程序的组件为目标。
*@param{String[]}支持事件一系列有效的DOM事件名称。默认值:['mousedown']。
*@return{ReactClass}
*/
导出默认值(目标,supportedEvents=['mousedown'])=>{
返回类ReactOutsideEvent扩展React.Component{
componentDidMount=()=>{
如果(!this.refs.target.onOutsideEvent){
抛出新错误('组件未定义“onOutsideEvent”方法');
}
supportedEvents.forEach((eventName)=>{
addEventListener(eventName,this.handleEvent,false);
});
};
组件将卸载=()=>{
supportedEvents.forEach((eventName)=>{
removeEventListener(eventName,this.handleEvent,false);
});
};
handleEvent=(事件)=>{
让目标,,
目标元素,
伊森赛德,
等外侧;
componentDidMount() {
document.addEventListener('click', this._handlePageClick);
},
componentWillUnmount() {
document.removeEventListener('click', this._handlePageClick);
},
_handlePageClick(e) {
var wasDown = this.mouseDownOnModal;
var wasUp = this.mouseUpOnModal;
this.mouseDownOnModal = false;
this.mouseUpOnModal = false;
if (!wasDown && !wasUp)
this.close();
},
_handleMouseDown() {
this.mouseDownOnModal = true;
},
_handleMouseUp() {
this.mouseUpOnModal = true;
},
render() {
return (
<Modal onMouseDown={this._handleMouseDown} >
onMouseUp={this._handleMouseUp}
{/* other_content_here */}
</Modal>
);
}
npm install --save react-onclickoutside
var Component = React.createClass({
mixins: [
require('react-onclickoutside')
],
handleClickOutside: function(evt) {
// ...handling code goes here...
}
});
/* Some react component */
...
showFoo = () => this.setState({ showFoo: true });
hideFoo = () => this.setState({ showFoo: false });
clicked = e => {
if (!this.state.showFoo) {
this.showFoo();
return;
}
e.preventDefault()
e.stopPropagation()
}
render() {
return (
<div
onFocus={this.showFoo}
onBlur={this.hideFoo}
onMouseDown={this.clicked}
>
{this.state.showFoo ? <FooComponent /> : null}
</div>
)
}
...
<div ref={(element) => { this.myElement = element; }}></div>
handleClickOutside(e) {
if (!this.myElement.contains(e)) {
this.setState({ myElementVisibility: false });
}
}
componentWillMount() {
document.addEventListener('click', this.handleClickOutside, false); // assuming that you already did .bind(this) in constructor
}
componentWillUnmount() {
document.removeEventListener('click', this.handleClickOutside, false); // assuming that you already did .bind(this) in constructor
}
<Modal onHide={this.closeFunction}>
...
</Modal>