Javascript 单击“主体”以更改“响应关闭”下拉列表中的状态

Javascript 单击“主体”以更改“响应关闭”下拉列表中的状态,javascript,reactjs,Javascript,Reactjs,我写了一个简单的下拉菜单,因为我想要不同的风格,并对行为有更多的控制,但现在我陷入了当用户点击身体或其他元素时关闭下拉菜单的困境。我如何通过纯反应实现这一点 var Hello = React.createClass({ getInitialState() { return { openDropdown: false } }, toggleDropdown: function() { this.setState({ o

我写了一个简单的下拉菜单,因为我想要不同的风格,并对行为有更多的控制,但现在我陷入了当用户点击身体或其他元素时关闭下拉菜单的困境。我如何通过纯反应实现这一点

var Hello = React.createClass({
  getInitialState() {
     return {
        openDropdown: false
     }
  },

  toggleDropdown: function() {
     this.setState({
         openDropdown: !this.state.openDropdown
     })
  },

  render: function() {
    return (
        <ul>
        <p onClick={this.toggleDropdown.bind(this)}>Select</p>
        <div className={this.state.openDropdown ? 'show' : 'hide'}>
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
        </div>
      </ul>

    )
  }
});
var Hello=React.createClass({
getInitialState(){
返回{
openDropdown:错误
}
},
toggleDropdown:function(){
这是我的国家({
openDropdown:!this.state.openDropdown
})
},
render:function(){
返回(

    选择

  • 项目1
  • 项目2
  • 项目3
) } });

在加载组件时向主体添加事件侦听器

componentDidMount: function() {
  document.body.addEventListener('click', this.closeDropdwn);
},

closeDropdwn: function() {
  this.setState({
    openDropdown: false,
  })
},

为了更好地理解,我重新命名了您的状态,同时,将渲染时的div更改为ul,li元素不应位于ul之外的任何其他元素中

此外,如果需要的话,还需要更多的拆分,以便更容易调试

var Hello = React.createClass({
    getInitialState() {
        return {
            isOpenDropdown: false //rename for better understanding
        }
    },

    toggleDropdown: function(e) {
        if(e && ReactDOM.findDOMNode(this.refs.dropdown).contains(e.target)) {
            return; //Ignore click if it was inside the dropdown
    }
    this.state.isOpenDropdown ? this.closeDropdown() : this.openDropdown()
},

openDropdown: function() {
    document.addEventListener("click", this.closeDropdown);
    this.setState({
        isOpenDropdown: true
    });
},

closeDropdown: function() {
    document.removeEventListener("click", this.closeDropdown);
    this.setState({
        isOpenDropdown: false
    });
}

componentWillUnmount: function() {
    if(this.state.isOpenDropdown){
        document.removeEventListener("click", this.closeDropdown);
    }
}

render: function() {
    //Changed "div" to "ul" -- LI should never be inside any element other than UL.
    return (
        <div>
        <p onClick={this.toggleDropdown.bind(this)}>Select</p>
        <ul className={this.state.isOpenDropdown ? 'show' : 'hide'}> 
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
        </ul>
        </div>

        )
}
});
var Hello=React.createClass({
getInitialState(){
返回{
isOpenDropdown:false//重命名以更好地理解
}
},
切换下拉菜单:函数(e){
if(e&&ReactDOM.findDOMNode(this.refs.dropdown).contains(e.target)){
return;//如果在下拉列表中,则忽略单击
}
this.state.isOpenDropdown?this.closeDropdown():this.openDropdown()
},
openDropdown:function(){
document.addEventListener(“单击”,此为“关闭”下拉列表);
这是我的国家({
等弯降:真
});
},
关闭下拉列表:函数(){
document.removeEventListener(“单击”此.closeDropdown);
这是我的国家({
等径降速:false
});
}
componentWillUnmount:function(){
if(this.state.isOpenDropdown){
document.removeEventListener(“单击”此.closeDropdown);
}
}
render:function(){
//将“div”更改为“ul”--LI不应位于ul以外的任何元素中。
返回(

选择

  • 项目1
  • 项目2
  • 项目3
) } });
只有
li
应该在
ul
内,尽管
li
内可以有任何其他内容,但没有看到另一个ul。我会解决的。如果我有多个下拉列表,这会有问题。是的。为了有多个下拉列表,您需要在打开下拉列表的状态下保存,并在单击body时仅关闭该下拉列表。