简体   繁体   English

Position 按钮设置为显示时的引导下拉菜单:无

[英]Position bootstrap dropdown when button set to display:none

Description描述

In VueJS I'm trying to open Bootstrap dropdown menu programmatically by clicking on a word.在 VueJS 中,我试图通过单击一个单词以编程方式打开 Bootstrap 下拉菜单。 I want the menu to appear right under the mouse.我希望菜单出现在鼠标正下方。

The problem问题

The problem is - when I set display: none;问题是 - 当我设置display: none; on the button that displays the dropdown, the menu appears on the top left corner.在显示下拉菜单的按钮上,菜单出现在左上角。 I've found solutions for HTML, but I struggle to rewrite them to VueJS.我找到了 HTML 的解决方案,但我很难将它们重写为 VueJS。

Minimal working example最小的工作示例

My current snippet looks like this: (click the word "click" or remove display: none; )我当前的片段如下所示:(单击“单击”一词或删除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>

The problem with setting the dropdown's button to display: none is that it's as if the button is no longer part of the DOM, and the dropdown uses the button's position to position itself.将下拉菜单的按钮设置为display: none的问题在于,好像按钮不再是 DOM 的一部分,并且下拉菜单使用按钮的 position 到 position 本身。

This problem can be avoided if you instead set the button to opacity: 0 .如果您将按钮设置为opacity: 0 ,则可以避免此问题。 It's still invisible, but the dropdown knows it's still there.它仍然不可见,但下拉列表知道它仍然存在。

The dropdown button with a few tweaked styles:带有一些调整的下拉按钮 styles:

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

Working snippet:工作片段:

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

Trading display:none;交易display:none; for opacity: 0; max-height: 0;padding:0; opacity: 0; max-height: 0;padding:0; opacity: 0; max-height: 0;padding:0; seems to do the trick.似乎可以解决问题。

Also note you're loading two different versions of Vue, which might cause unexpected behavior.另请注意,您正在加载两个不同版本的 Vue,这可能会导致意外行为。


However, it's still not a good enough solution.但是,它仍然不是一个足够好的解决方案。 The proper solution is to treat the <span> element as the dropdown button, removing the button-like styling.正确的解决方案是将<span>元素视为下拉按钮,删除类似按钮的样式。

Why?为什么? Because the dropdown is positioning itself relative to the current parent, which is the text paragraph.因为下拉菜单相对于当前父级(即文本段落)定位自身。 So it will always be aligned to the left side.因此它将始终与左侧对齐。 As for vertical position, it will be correct as long as the trigger element is on the row immediately above the dropdown.至于垂直 position,只要触发元素位于下拉列表正上方的行上,它就是正确的。 If any wrapping occurs in between them, the dropdown will be displayed too low.如果它们之间发生任何换行,下拉列表将显示得太低。

So here's what I believe to be the right way of doing it:所以这就是我认为正确的做法:

 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM