单击或悬停在菜单区域之外时关闭反应按钮下拉菜单

2024-05-26

在我的反应应用程序中,其中一个组件正在创建一个按钮下拉菜单,如下所示。

<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>

如果有人单击/悬停在该菜单区域之外的任何位置,我如何关闭该菜单?


不要在 React 中使用 jQuery 事件和 DOM 操作,你没有抓住重点。
你有一个state use it!

在下面的示例中,您可以看到我删除了所有jquery.js and bootstrap.js文件并仅保留bootstrap.css.
我用state为了显示/隐藏<ul>列表(我已将其设置为display: block为了覆盖默认值display: none of bootstrap.css).
我设置了 2 个关于显示和隐藏的主要处理程序<ul>和 1 个处理程序onclick每个项目的:

  1. toggleShow()- 切换show财产在state附于onBlur按钮的。
  2. hide()- 隐藏<ul>当然是通过状态(它做了一个 更多的事情我会解释)。
  3. doSomething()- 单击某个项目时将触发。

不过,当我们隐藏<ul>我们无法处理点击事件。

But why?

因为我们并没有真正隐藏它,所以当state.show是假的。所以基本上存在一种竞争条件setState触发针对处理程序的重新渲染doSomething无法运行的事件处理程序。
所以这里的挑战是确定是否触发了活动元素onBlur按钮的事件是里面的项目<ul>。如果是,那么我们需要让该项目触发它onClick事件,然后才设置状态并“隐藏”.
我们在以下人员的帮助下做到了这一点relatedTarget附加到event。这就是我们正在寻找的活跃元素,如果我们有一个但它不是null然后我们触发它的点击事件(无论它是什么元素,因为我们不关心),然后我们用show: false.

一个工作示例:

class DropDown extends React.Component{
  constructor(props){
    super(props);

    this.state = {
      show: false
    }
    this.doSomething = this.doSomething.bind(this);
    this.toggleShow = this.toggleShow.bind(this);
    this.hide = this.hide.bind(this);
  }

  doSomething(e){
    e.preventDefault();
    console.log(e.target.innerHTML);
  }

  toggleShow(){
    this.setState({show: !this.state.show});
  }

  hide(e){
    if(e && e.relatedTarget){
      e.relatedTarget.click();
    }
    this.setState({show: false});
  }
  
  render(){
    return(
      <div className="dropdown">
        <button 
          className="btn btn-primary dropdown-toggle"
          type="button"
          onClick={this.toggleShow}
          onBlur={this.hide}
        >

        {"Dropdown Example"}
          
        <span className="caret"></span>
        </button>
        {
          this.state.show &&
        (
          <ul className="dropdown-menu" style={{display: 'block'}}>
          <li><a onClick={this.doSomething} href="#">HTML</a></li>
          <li><a onClick={this.doSomething} href="#">CSS</a></li>
          <li><a onClick={this.doSomething} href="#">JavaScript</a></li>
        </ul>
        )
        }
      </div>
    );
  }
}


ReactDOM.render(<DropDown />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div id="root"></div>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单击或悬停在菜单区域之外时关闭反应按钮下拉菜单 的相关文章

随机推荐

  • 即使使用 return 语句,带有 forEach 的函数也返回未定义

    我只是创建一个函数来检查对象数组中某些内容的值 但由于某种原因它不断返回undefined 这是为什么 Demo http jsfiddle net cNYwz 1 http jsfiddle net cNYwz 1 var data Ke
  • WPF - 普通 [标签:输入] 控制的最佳实践

    我想知道 这是在 WPF 中获取众所周知的标签输入 或输出 无关紧要 组合的最佳和最快的方法 这是一个简单的任务 只需考虑 对象 ME 的快速输出 名字 克里斯蒂安 年龄 28 心情 好 我知道 我可以使用带有文本块的网格 但说实话 这个
  • 如何将多个值存储到一个键(java)

    我搜索一个可以存储多个键值对的数据结构 数据基本上是这样的 1 value 1 2 value 2 于是我想到了使用HashMap 遗憾的是 这对我不起作用 因为一个键可能会出现多个值 在上面的例子中 1 value 2 可能是另一个条目
  • 如何在 Azure DevOps 发布管道中保存测试结果

    在发布管道期间 我将启动 Selenium 测试 如果这些测试失败 则会进行屏幕截图 我正在寻找一种上传它们的方法 以便我可以查看它们并检查出了什么问题 我设法将它们压缩 但不幸的是 所有上传方法都不适用于发布管道 有没有办法在发布管道期间
  • 如何从网上获取源代码?

    我正在尝试从 Web 获取 HTML 源代码 我尝试这样做 u new URL url URLConnection con u openConnection con setRequestProperty User Agent Mozilla
  • 如何在Retrofit(Android)中动态设置标题

    我使用的 API 使用授权方案 需要设置特殊的 X Authorization 标头来验证请求 例如 此 Retrofit 设置非常适合其身份验证令牌为abc123 Headers X Authorization abc123 GET po
  • 连接到 JIRA 时 Bitbucket 问题部分无用?

    我已将 Bitbucket 存储库与 JIRA 项目连接起来 现在 当我提交到 Bitbucket 时 我可以引用 JIRA 问题 或者可以在 JIRA 的 Bitbucket 存储库中创建分支并查看 JIRA 的提交 但是 当我在 JIR
  • Java SSO 与 Wildfly 8、Java 1.8.0_45 和 Active Directory

    我对这个主题进行了很多搜索 但找不到解决方案 要求的简短描述 Wildfly 8 2 下 Web 应用程序上的 SSO 在 Active Directory 中验证 Windows 用户的身份 当 SSO 失败时回退到登录表单 在 Wild
  • 如何从更高级别启动用户级别的 Exe

    我希望一个进程始终在用户级别运行 当它由以管理员级别运行的安装程序 自定义 而不是 msi 启动时 或者当用户登录时 环顾四周 我不确定这是否可能 最简单的方法是有 2 个进程 一种是普通用户 它启动提升 管理进程 然后管理进程可以使用 I
  • QFileDialog 作为 TableView 的编辑器:如何获取结果?

    我正在使用一个QFileDialog作为某些专栏的编辑QTableView 这基本上有效 对一些焦点问题取模 请参阅here https stackoverflow com questions 22854242 qfiledialog as
  • iOS - 确保在主线程上执行[重复]

    这个问题在这里已经有答案了 我想知道如何打电话给我function on the 主线程 我如何确保我的function被称为主线程 这是继之前的question https stackoverflow com questions 1105
  • 如何在服务器上使用 ffmpeg 从 WebRTC 流获取音频和视频

    我正在尝试从 WebRTC 流获取音频和视频 并在 ubuntu 服务器上使用 ffmpeg 处理它 转码或转储 我天真地期望它能简单地解释 WebRTC 提供的 sdp 但我错了 我怀疑 ffmpeg 无法发回答案 sdp 必须手动完成
  • C# 锁(mylocker) 不起作用

    我有很多 Web 服务调用 异步 在回调中 我会将结果绘制到 Excel 中 我想同步绘图方法 所以我使用以下内容 但是 从我在 Visual Studio 中追踪到 每次 lock locker 都会成功 并且有许多线程运行clearco
  • cmake 找不到 Qt4

    由于4 8 0已经发布 我重新安装了Qt 现在我也想使用cmake 为了使 cmake 工作 我记得必须添加 mingw bin 文件夹 QtSDK Desktop Qt 4 7 3 到Qt4 7 3中的PATH 所以我猜测在中会有一个类似
  • 在 Docker 容器中以主机用户身份运行

    在我的团队中 我们在进行开发时使用 Docker 容器在本地运行我们的网站应用程序 假设我正在开发 Flask 应用程序app py具有依赖关系requirements txt 工作流程大致如下 I am robin and I am in
  • NoneType 类型的对象没有 len

    def medianeven L while len L gt 2 L L 1 len L 1 return average L def medianodd L while len L gt 1 L L 1 len L 1 return L
  • 了解 VerQueryValue

    在 MSDN 上 我注意到 VerQueryValue 函数的以下内容 lplp缓冲区 输出 低电压空洞当此方法返回时 包含指向 pBlock 指向的缓冲区中所请求版本信息的指针的地址 当关联的 pBlock 内存被释放时 lplpBuff
  • f.read 为空

    我在解释器中完成这一切 loc1 council council1 file1 open loc1 r 此时我可以执行 file1 read 并将文件的内容作为字符串打印到标准输出 但如果我添加这个 string1 file1 read 字
  • 在Java中打印时差最惯用的方法是什么?

    我熟悉以毫秒为单位的打印时间差 long time System currentTimeMillis do something that takes some time long completedIn System currentTime
  • 单击或悬停在菜单区域之外时关闭反应按钮下拉菜单

    在我的反应应用程序中 其中一个组件正在创建一个按钮下拉菜单 如下所示 div class dropdown div