在我的反应应用程序中,其中一个组件正在创建一个按钮下拉菜单,如下所示。
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a onClick=doSomething href="#">HTML</a></li>
<li><a onClick=doSomething href="#">CSS</a></li>
<li><a onClick=doSomething href="#">JavaScript</a></li>
</ul>
</div>
如果有人点击/悬停在此菜单区域之外的任何位置,我该如何关闭此菜单?
答案 0 :(得分:5)
不要在你的React中使用jQuery事件和DOM操作,你忽略了这一点
您有state
使用它!
在以下示例中,您可以看到我删除了所有jquery.js
和bootstrap.js
个文件,并且只保留了bootstrap.css
。
我使用state
来显示/隐藏<ul>
列表(我已将其设置为display: block
,以覆盖display: none
的默认bootstrap.css
)。
我已经设置了2个主要处理程序,用于显示和隐藏每个项目<ul>
的{{1}}和1个处理程序:
onclick
- 切换附加到按钮的toggleShow()
的{{1}}中的show
媒体资源。state
- 通过当然状态隐藏onBlur
(它会做一个
更多我将解释的事情。)hide()
- 点击某个项目时会触发。这种情况有一个很好的挑战,当我们隐藏<ul>
时,我们无法处理click事件。
但为什么?
因为我们并没有真正隐藏它,所以当doSomething()
为false时它不会被渲染。所以基本上有一种<ul>
触发器的竞争条件是对state.show
事件处理程序的处理程序进行重新渲染而无法运行。
因此,这里的挑战是确定触发按钮的setState
事件的活动元素是否是doSomething
内的项目。如果是,那么我们需要让该项触发它的onBlur
事件,然后才设置状态并“隐藏”。
我们是在附加到<ul>
的{{1}}的帮助下完成的。这是我们正在寻找的活跃元素,如果我们有一个并且它不是onClick
那么我们就会触发它的点击事件(无论我们不关心它的方式是什么元素),并且只有然后我们用relatedTarget
设置状态。
一个工作示例:
event
null
答案 1 :(得分:2)
有几种方法可以做到这一点。最简单的方法是让事件监听器监听click事件或为dropdown组件编写onBlur函数。
componentWillMount() {
document.body.addEventListener('click', this.handleClick);
}
componentWillUnmount() {
document.body.removeEventListener('click', this.handleClick);
}
然后你必须将你的组件包装在监听器组件中。
这是工作的JS小提琴。 https://jsfiddle.net/vamshikrishna144/zukcpfr2/