通过在 Javascript 中单击外部来关闭下拉菜单(教程说明)

2024-01-08

我尝试通过以下方式使用 Javascript 实现打开和关闭下拉菜单的方法this https://www.w3schools.com/howto/howto_js_dropdown.aspw3schools.com 上的教程。虽然“显示”下拉菜单的功能有效,但关闭下拉菜单的功能却不起作用。此外,这段代码旁边没有任何解释来解释为什么它should工作,使得调试变得困难。

/* When the user clicks on the button, 
toggle between hiding and showing the dropdown content */
function myFunction() {
    document.getElementById("myDropdown").classList.toggle("show");
}

// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
  if (!event.target.matches('.dropbtn')) {

    var dropdowns = document.getElementsByClassName("dropdown-content");
    var i;
    for (i = 0; i < dropdowns.length; i++) {
      var openDropdown = dropdowns[i];
      if (openDropdown.classList.contains('show')) {
        openDropdown.classList.remove('show');
      }
    }
  }
}

因此,我的问题是

1)是否有教程中的代码should用于关闭下拉菜单的目的。 (已回答)

2)为了让我自己和未来遇到相同教程和问题的新手清楚起见,有人可以澄清这应该如何/为什么起作用吗? (未答复)

编辑(我的尝试):

HTML:

<div class="sharedown">     
    <p onclick="shareVis()" class="sharebtn">&nbsp Share</p>
    <div id="mySharedown" class="sharedown-content">
        <a href="#">Self</a>
        <p>User</p><input type="text" name="user-name" placeholder="Share to">
        <a href="#">Community</a>
    </div> 
</div>

JS:

function shareVis() {
    document.getElementById("mySharedown").className = "show";
}

window.onclick = function(event) {
    if (!event.target.matches('sharebtn')) {

        var sharedowns = document.getElementsByClassName("sharedown-content");
        var i;
        for (i = 0; i < sharedowns.length; i++) {
            var openSharedown = sharedowns[i];
            if (openSharedown.classList.contains('show')) {
                openSharedown.classList.remove('show');
            }
        }
    }   
}

CSS:

/* Share dropdown menu */

p.sharebtn {

    color: darkgrey;
    font-family:calibri;
    padding: 0px;
    margin: 0px;
    font-size: 12;
    border: none;
    cursor: pointer;
    display:    inline; 
}

/* Dropdown button on hover & focus */
p.sharebtn:hover, p.sharebtn:focus {
    color: grey;

}

/* The container <div> - needed to position the dropdown content */

.sharedown {
    position: relative;
    display:    inline-block;   

}

/* Dropdown Content (Hidden by Default) */
.sharedown-content {
    display: none;
    position: absolute;
    background-color:   #f1f1f1;
    min-width:  100px;
    box-shadow: 0 2px 4px 1px #C4E3F5;
    z-index:1; /* place dropdown infront of everything else*/
}

.sharedown-content a { 
color: black;
padding: 5px 5px;
text-decoration: none;
display: block;
}

/* Show the dropdown menu (use JS to add this class to the .dropdown-
content container when the user clicks on the dropdown button) */

.show {display: block;
    position: absolute;
    background-color:   #f1f1f1;
    min-width:  100px;
    box-shadow: 0 2px 4px 1px #C4E3F5;
    opacity: 1;
    z-index:1;}

问题在于shareVis功能。这里

document.getElementById("mySharedown").className = "show";

你正在替换#mySharedown类名至show。然后在window.onclick

var sharedowns = document.getElementsByClassName("sharedown-content");

你没有得到任何sharedowns因为您已经将类名替换为show.


You can either add show class into classList
document.getElementById("mySharedown").classList.add("show");

或将类名替换为sharedown-content show

document.getElementById("mySharedown").className = "sharedown-content show";

工作解决方案如下:

function shareVis() {
    //document.getElementById("mySharedown").className = "sharedown-content show";
    document.getElementById("mySharedown").classList.add("show");
}

window.onclick = function(event) {
    if (!event.target.matches('.sharebtn')) {

        var sharedowns = document.getElementsByClassName("sharedown-content");
        var i;
        for (i = 0; i < sharedowns.length; i++) {
            var openSharedown = sharedowns[i];
            if (openSharedown.classList.contains('show')) {
                openSharedown.classList.remove('show');
            }
        }
    }
}

document.getElementById("mySharedown").addEventListener('click',function(event){
    event.stopPropagation();
});
#mySharedown{
  display: none;
  border: 1px solid black;
}

#mySharedown.show {
  display: block;
}
<div class="sharedown">     
    <p onclick="shareVis()" class="sharebtn">&nbsp Share</p>
    <div id="mySharedown" class="sharedown-content">
        <a href="#">Self</a>
        <p>User</p><input type="text" name="user-name" placeholder="Share to">
        <a href="#">Community</a>
    </div> 
</div>

Update

为了防止第二次点击#mySharedown躲起来#mySharedown,你应该添加另一个click活动为#mySharedown并防止它冒泡,就像这样

document.getElementById("mySharedown").addEventListener('click',function(event){
    event.stopPropagation();
});

更新包含在工作解决方案中

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过在 Javascript 中单击外部来关闭下拉菜单(教程说明) 的相关文章

随机推荐

  • OxyPlot - 如何删除轴

    我想创建一个没有任何可见轴的 Oxyplot 视图 谁能告诉我该怎么做 为了避免误解 我从未在绘图模型中添加任何轴 此代码已经添加了轴 如何避免它们被显示 C plot new PlotModel var ser new LineSerie
  • FirebaseRecyclerAdapter 和 Android 上的多种项目类型

    我想添加 2 种类型 有图像 没有图像 in my recyclerview 我知道我需要重写方法FirebaseRecyclerAdapter但我不知道怎么做 请帮我解决这个问题 Override public int getItemVi
  • Spark Streaming 2.0.0 - 在负载下几天后冻结

    我们在带有 Spark 2 0 0 的 AWS EMR 5 0 0 上运行 从 125 个分片 Kinesis 流中使用 使用 2 个消息生成器提供 19k 个事件 秒 每条消息大小约为 1k 使用 20 台机器组成的集群进行消费 该代码有
  • 如何将 Kafka 承诺的消费者偏移量更改为所需的偏移量

    我有卡夫卡流应用程序 我的应用程序正在成功处理事件 如何使用所需的偏移量更改 Kafka 提交的消费者偏移量以重新处理 跳过事件 我试过如何更改主题的起始偏移量 https stackoverflow com questions 29791
  • Zend 2 中两个表的并集

    我想用 zf2 中的 where 子句合并两个表 表1 app followers表2 应用程序用户其中条件可以是任何东西并按updated date 排序 请让我知道 zend 2 的查询 Thanks Using UNION is ZF
  • 在OData中引入自定义属性

    在我的数据库用户表中 我有名为 DateDeleted 的 DateTime 字段 当用户存在时该字段为空 并且当用户 被删除 时设置为正确的值 我想知道是否有一种方法可以为 User 实体引入 IsDeleted 属性 以便 http o
  • 如何将解析后的数据从一个单元格提取到另一个单元格

    给定一个电子表格单元格 其中包含一个由一系列连字符连接的字符段组成的字符串 我需要提取最后一个段 例如 考虑 A 列包含数据字符串 例如XX XXX X XX XX G10 where X表示任意字符 我需要在 B 列中输入什么公式才能得到
  • 使用 Javascript 在多个 CSS 文件之间切换

    我目前正在尝试制作一系列按钮 网站的用户可以单击这些按钮来在不同的 CSS3 文件之间进行更改 这将改变某些效果 为了实现这个目标 我需要某种方式来访问 href example1 css 我的 HTML 中的标签 并将其更改为 href
  • Jenkins - 最大并发作业数

    我可以在 Jenkins 中同时运行的最大作业数是多少 Jenkins 作业的最大数量取决于您在主站和从站中设置的限制 通常 我们会限制核心数量 但您的里程可能会有所不同 具体取决于可用内存 磁盘速度 SSD 的可用性以及源代码的重叠 对于
  • 如何更改 F# 交互式换行符

    在 fs 文件中 换行符表示为 r n 但在 F 交互窗口中是 n 在我当前正在尝试解决的问题中 多行文字字符串的长度很重要 因此 当我在 F 交互窗口中测试代码时出现问题 因为字符串的长度与正常执行时的长度不同 我希望有一个选项可以将 F
  • jQuery DataTables sDom 命令不起作用

    我需要左上角的 过滤器 和右上角的 大小 但不起作用 document ready function jQuery example dataTable sDom lt top fl gt rt lt bottom ip gt lt clea
  • 在vba中一次循环遍历所有可用的自动筛选条件

    我想知道是否有一种方法可以获取列表中所有不同的自动过滤条件 以便迭代每个条件 最后复制并粘贴每个不同的表 这些表在迭代时会显示在单独的工作表中 理想情况下 这将运行 n 次 ActiveSheet Range AllRows AutoFil
  • 我应该关心 React Redux 应用程序中的状态变化率吗?

    我正在使用 React Redux 和 Websocket 实现 评估 实时 Web 应用程序 在服务器上 我的数据集以每秒大约 32 次更改的速度发生更改 每次更改都会使用 Websocket 向应用程序发送一条异步消息 异步消息在我的
  • 用于 Java 的 LZ4 和 Zstd

    是否有适用于 LZ4 和 ZStd 的最佳 Java 压缩库 我尝试过 apache commons 这是 zstd jni 实现 String fileURL TestFileUtil getFileURL TestFileCategor
  • 实现 (.m) 文件中的 IBOutlet 实例变量

    假设我有一个视图控制器或窗口控制器 它 像往常一样 是相应 XIB 文件中的 文件所有者 众所周知 这是很常见的IBOutlet然后您可以使用 Interface Builder 在 XIB 中连接控制器类 到目前为止 我一直在创造IBOu
  • 选择以下划线(_)开头的所有对象键

    我需要在以下对象中创建一个包含所有键 而不是值 的数组 其中键以下划线开头 在下面的代码片段中我试图得到getSubscriptions 回来 foo1 foo2 let myObj foo0 test foo1 test foo2 tes
  • 使用 JavaScript 在浏览器中触发全屏 [重复]

    这个问题在这里已经有答案了 可能的重复 如何在Javascript中制作全屏窗口 伸展到整个屏幕 https stackoverflow com questions 1125084 how to make in javascript ful
  • 禁用 DrawerLayout 的稀松布触摸手势

    我需要禁用稀松布上的触摸手势 红色突出显示的部分 我只想通过滑动来关闭抽屉 问题是 当抽屉布局打开并且我需要从红色突出显示部分下方的 ListView 中选择一个元素时 发生的情况是抽屉关闭 只有此时我才能从 ListView 中选择一个元
  • Jenkinsfile 参数化构建中的环境和参数之间有什么关系?

    最近 我在与同事一起进行 Jenkins 构建时遇到了一些难题 他一直在使用params VARIABLE and env VARIABLE可以互换并且没有任何问题 与此同时 我开始在他通过这行代码的环境对参数对象的调用之一中收到空对象错误
  • 通过在 Javascript 中单击外部来关闭下拉菜单(教程说明)

    我尝试通过以下方式使用 Javascript 实现打开和关闭下拉菜单的方法this https www w3schools com howto howto js dropdown aspw3schools com 上的教程 虽然 显示 下拉