【问题标题】:Position bootstrap dropdown when button set to display:none当按钮设置为显示时定位引导下拉菜单:无
【发布时间】:2020-08-31 12:26:02
【问题描述】:

说明

在 VueJS 中,我试图通过单击一个单词以编程方式打开 Bootstrap 下拉菜单。 我希望菜单出现在鼠标正下方。

问题

问题是 - 当我在显示下拉菜单的按钮上设置 display: none; 时,菜单出现在左上角。我为 HTML 找到了 solutions,但我很难将它们重写为 VueJS。

最小的工作示例

我当前的 sn-p 看起来是这样的:(点击“点击”一词或删除display: none;

new Vue({
  el: '#vue-app',
  methods: {
    toggleTest: function(e) {
      e.stopPropagation();
      console.log(this.$refs.clickWord);
      this.$refs.clickWord.click();
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>



<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="vue-app">

  <div class="container">

    <div class="row">
      <div class="col-6">
        A column.
      </div>
      <div class="col-6">
        You should <span v-on:click="toggleTest" onMouseOver="this.style.background='#AFF'" onMouseOut="this.style.background='#FFF'">click</span> a word.

        <div class="dropdown" id="word0">
          <button id="ete" style="display:none" ref="clickWord" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                Dropdown
              </button>
          <div class="dropdown-menu" style="top:100 !important; left:100; position: absolute;">
            <span class="dropdown-item-text">Dropdown item text</span>
            <a class="dropdown-item" href="#">Action</a>
            <a class="dropdown-item" href="#">Another action</a>
            <a class="dropdown-item" href="#">Something else here</a>
          </div>
        </div>
      </div>
    </div>


  </div>
</div>

【问题讨论】:

    标签: javascript html css vue.js bootstrap-4


    【解决方案1】:

    将下拉菜单的按钮设置为display: none 的问题在于,就好像按钮不再是 DOM 的一部分,而下拉菜单使用按钮的位置来定位自己。

    如果您将按钮设置为opacity: 0,则可以避免此问题。它仍然不可见,但下拉列表知道它仍然存在。

    带有一些调整样式的下拉按钮:

    <button id="ete"
            style="opacity:0; height:0; position:absolute; top:-16px"
            ref="clickWord"
            class="btn btn-secondary dropdown-toggle"
            type="button"
            data-toggle="dropdown"
            aria-haspopup="true"
            aria-expanded="false"></button>
    

    工作sn-p:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    
    
    
    <script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
    <div id="vue-app">
    
      <div class="container">
    
        <div class="row">
          <div class="col-6">
            A column.
          </div>
          <div class="col-6">
            You should
            <span v-on:click="toggleTest"
              onMouseOver="this.style.background='#AFF'"
              onMouseOut="this.style.background='#FFF'">click</span>
            a word.
    
            <div class="dropdown" id="word0">
              <button id="ete"
              style="opacity:0; height:0; position:absolute; top:-16px"
              ref="clickWord" class="btn btn-secondary dropdown-toggle"
              type="button" data-toggle="dropdown" aria-haspopup="true"
              aria-expanded="false"></button>
              <div class="dropdown-menu"
                style="top:100 !important; left:100; position: absolute;">
                <span class="dropdown-item-text">Dropdown item text</span>
                <a class="dropdown-item" href="#">Action</a>
                <a class="dropdown-item" href="#">Another action</a>
                <a class="dropdown-item" href="#">Something else here</a>
              </div>
            </div>
          </div>
        </div>
    
    
      </div>
    </div>
    
    
    <script>
    new Vue({
      el: '#vue-app',
      methods: {
        toggleTest: function(e) {
          e.stopPropagation();
          // console.log(this.$refs.clickWord);
          this.$refs.clickWord.click();
        }
      }
    });
    </script>

    【讨论】:

      【解决方案2】:

      display:none; 换取opacity: 0; max-height: 0;padding:0; 似乎可以解决问题。

      另请注意,您正在加载两个不同版本的 Vue,这可能会导致意外行为。


      但是,它仍然不是一个足够好的解决方案。正确的解决方案是将&lt;span&gt; 元素视为下拉按钮,移除按钮式样式。

      为什么?因为下拉菜单相对于当前父级(即文本段落)定位自身。因此它将始终与左侧对齐。至于垂直位置,只要触发元素位于下拉列表正上方的行上,它就是正确的。如果它们之间发生任何换行,下拉列表将显示得太低。

      以下是我认为正确的做法:

      Vue.config.productionTip = false;
      Vue.config.devtools = false;
      
      new Vue({
        el: '#vue-app'
      });
      <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
      <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
      
      <div id="vue-app">
        <div class="container">
          <div class="row">
            <div class="col-6">
              A column.
            </div>
            <div class="col-6">
              You should <span onMouseOver="this.style.background='#AFF'" onMouseOut="this.style.background='#FFF'" class="dropdown">
                <span data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                      click
                </span>
                <div class="dropdown-menu">
                  <span class="dropdown-item-text">Dropdown item text</span>
                  <a class="dropdown-item" href="#">Action</a>
                  <a class="dropdown-item" href="#">Another action</a>
                  <a class="dropdown-item" href="#">Something else here</a>
                </div>
              </span> a word.
            </div>
          </div>
        </div>
      </div>

      【讨论】:

      • 你显然不再需要 Vue 来实现这一点。定位下拉菜单的所有繁重工作都是由 Bootstrap 的 js 完成的。在这里,Vue 的一个有趣用途是在单击任何单词时动态放置下拉列表,同时将其保存在模板中并在需要的地方动态呈现。另一个注意事项:您可能想查看 BootstrapVue - 它是使用 Vue 构建的一组无 jQuery 的 Bootstrap 组件,适用于 Vue。它非常直观并且效果很好。如果你想使用 Vue 和 Bootstrap,你应该试一试。
      • 你所描述的是我的最终目标。我想要多个触发下拉菜单的单词。下拉菜单应出现在光标(也称为任何单词)的正下方,并根据所选单词动态加载下拉内容。而且我认为在光标下显示内容可以解决问题,而当前的解决方案需要我编写多个按钮 - 每个按钮都有一个可点击的单词。我想我过于简化了我的问题,它允许许多替代解决方案:)
      猜你喜欢
      • 2014-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-09
      • 1970-01-01
      • 2013-10-10
      相关资源
      最近更新 更多