Opening a bootstrap5 dropdown programmatically only works in the browser's dev console, not in vanilla JS code

huangapple go评论97阅读模式
英文:

Opening a bootstrap5 dropdown programmatically only works in the browser's dev console, not in vanilla JS code

问题

我尝试在我的Web应用程序中点击链接时打开Bootstrap5下拉菜单。我尝试分发事件并使用Bootstrap下拉菜单类,但都没有成功。这两种方法的代码在开发者控制台中运行时都有效(Firefox和Chromium)。

我去掉了除Bootstrap之外的一切,并编写了这个微型网站,以确保没有其他东西干扰代码:

<html>
<head>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
  <script>
    function test() {
      document.getElementById("dropdownMenuButton1").click();
    }
  </script>
</head>
<body>
  <!-- 这是官方Bootstrap5文档中的下拉示例 -->
  <div class="dropdown">
    <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
      Dropdown button
    </button>
    <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
      <li><a class="dropdown-item" href="#">Action</a></li>
      <li><a class="dropdown-item" href="#">Another action</a></li>
      <li><a class="dropdown-item" href="#">Something else here</a></li>
    </ul>
  </div>
  <!-- 现在是应该触发下拉菜单点击的按钮 -->
  <button class="btn btn-primary" onclick="test()">Open Dropdown</button>
</body>
</html>

它不起作用,但当我在开发控制台中运行以下代码时,下拉菜单会打开:

document.getElementById("dropdownMenuButton1").click();
英文:

I tried to open a Bootstrap5 dropdown when clicking a link in my web app. I tried dispatching events and using the bootstrap Dropdown classes, both without success. The code of both approaches works, when I run it in the developers console (Firefox & Chromium).

I stripped everything but bootstrap and wrote this micro website to make sure nothing else interferes with the code:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;html&gt;

&lt;head&gt;
  &lt;link href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css&quot; rel=&quot;stylesheet&quot; integrity=&quot;sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3&quot; crossorigin=&quot;anonymous&quot;&gt;
  &lt;script src=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js&quot; integrity=&quot;sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
  &lt;script&gt;
    function test() {
      document.getElementById(&quot;dropdownMenuButton1&quot;).click();
    }
  &lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;
  &lt;!-- This is the dropdown example from the official bootstrap5 docs --&gt;
  &lt;div class=&quot;dropdown&quot;&gt;
    &lt;button class=&quot;btn btn-secondary dropdown-toggle&quot; type=&quot;button&quot; id=&quot;dropdownMenuButton1&quot; data-bs-toggle=&quot;dropdown&quot; aria-expanded=&quot;false&quot;&gt;
    Dropdown button
  &lt;/button&gt;
    &lt;ul class=&quot;dropdown-menu&quot; aria-labelledby=&quot;dropdownMenuButton1&quot;&gt;
      &lt;li&gt;&lt;a class=&quot;dropdown-item&quot; href=&quot;#&quot;&gt;Action&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a class=&quot;dropdown-item&quot; href=&quot;#&quot;&gt;Another action&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a class=&quot;dropdown-item&quot; href=&quot;#&quot;&gt;Something else here&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;
  &lt;!-- Now the button, that should trigger a click on the dropdown --&gt;
  &lt;button class=&quot;btn btn-primary&quot; onclick=&quot;test()&quot;&gt;Open Dropdown&lt;/button&gt;
&lt;/body&gt;

&lt;/html&gt;

<!-- end snippet -->

It's not working, but when I run

document.getElementById(&quot;dropdownMenuButton1&quot;).click();

in the dev console, the dropdown opens.

答案1

得分: 1

点击按钮将焦点移至按钮,因此 JavaScript 运行,触发下拉菜单打开,然后焦点移至按钮。

下拉菜单设计成在失去焦点时关闭,因此当焦点移到按钮时,它再次关闭(这一过程发生得非常快,以至于似乎一开始并未打开)。

您可以使用 autoClose 选项来更改这种行为。

英文:

Clicking the button moves the focus to the button, so the JavaScript runs, triggers the drop down to open, then the focus moves to the button.

The drop down menu is designed to close when it loses the focus, so when the focus moves to the button, it closes again (and this happens so quickly that it doesn't appear to open in the first place).

You can use the autoClose option to change that behaviour.

答案2

得分: -1

感谢 @Quentin 提供有关自动关闭选项的提示。我仍然不明白为什么在开发者控制台中单击事件可以正常工作,但在网站上的脚本中不能。

不过,我成功通过以下方法解决了这个问题:

<!DOCTYPE html>
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<script>
function test(){
  const elm = document.getElementById("dropdownMenuButton1");
  //  这会禁用自动关闭
  elm.setAttribute("data-bs-auto-close", "false");
  //  现在打开下拉菜单
  new bootstrap.Dropdown(elm).show();
  //  恢复原始状态
  elm.removeAttribute("data-bs-auto-close");
  //  重新创建下拉菜单以应用原始状态。
  //  如果没有延迟,它不起作用(不会打开)。
  setTimeout(() => {
    new bootstrap.Dropdown(elm);
  }, 10);
}
</script>
</head>
<body>
<!-- 这是来自官方 Bootstrap 5 文档的下拉示例 -->
<div class="dropdown">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
    下拉按钮
  </button>
  <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
    <li><a class="dropdown-item" href="#">操作</a></li>
    <li><a class="dropdown-item" href="#">另一个操作</a></li>
    <li><a class="dropdown-item" href="#">这里有其他东西</a></li>
  </ul>
</div>
<!-- 现在的按钮,应该触发下拉菜单的点击 -->
<button class="btn btn-primary" onclick="test()">打开下拉菜单</button>
</body>
</html>

这样可以通过单击其他元素来打开下拉菜单,并保持下拉菜单的原始行为。

英文:

Thanks @Quentin for the hint with the autoclose options. I still don't understand why the click event works in the developers console, but not in the script on the website.

However I managed to solve the problem with this hacky approach:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;html&gt;
&lt;head&gt;
&lt;link href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css&quot; rel=&quot;stylesheet&quot; integrity=&quot;sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3&quot; crossorigin=&quot;anonymous&quot;&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js&quot; integrity=&quot;sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
&lt;script&gt;
function test(){
const elm = document.getElementById(&quot;dropdownMenuButton1&quot;);
//  this disables the auto closing
elm.setAttribute(&quot;data-bs-auto-close&quot;, &quot;false&quot;);
//  now open the dropdown
new bootstrap.Dropdown(elm).show();
//  restore the original state
elm.removeAttribute(&quot;data-bs-auto-close&quot;);
//  recreate the dropdown to apply the original state.
//  without the timeout it does not work (it&#39;s not opening).
setTimeout(() =&gt; {
new bootstrap.Dropdown(elm);
}, 10);
}
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;!-- This is the dropdown example from the official bootstrap5 docs --&gt;
&lt;div class=&quot;dropdown&quot;&gt;
&lt;button class=&quot;btn btn-secondary dropdown-toggle&quot; type=&quot;button&quot; id=&quot;dropdownMenuButton1&quot; data-bs-toggle=&quot;dropdown&quot; aria-expanded=&quot;false&quot;&gt;
Dropdown button
&lt;/button&gt;
&lt;ul class=&quot;dropdown-menu&quot; aria-labelledby=&quot;dropdownMenuButton1&quot;&gt;
&lt;li&gt;&lt;a class=&quot;dropdown-item&quot; href=&quot;#&quot;&gt;Action&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;dropdown-item&quot; href=&quot;#&quot;&gt;Another action&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;dropdown-item&quot; href=&quot;#&quot;&gt;Something else here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;!-- Now the button, that should trigger a click on the dropdown --&gt;
&lt;button class=&quot;btn btn-primary&quot; onclick=&quot;test()&quot;&gt;Open Dropdown&lt;/button&gt;
&lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

This makes it possible to open the dropdown by clicking another element and keep the original behavior of the dropdown menu.

huangapple
  • 本文由 发表于 2023年7月31日 19:27:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76803177.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定