自定义下拉菜单,其中父级隐藏了溢出

时间:2019-11-27 17:34:49

标签: javascript html css drop-down-menu

据我所知,在Web客户端上构建自定义选择框存在某种问题。基本上,它可以归结为2个高级选项:

  1. 将选项下拉列表附加到元素本身。在这种情况下,如果选择框的父级具有overflow: hidden,则下拉菜单将在溢出时被裁剪。
  2. 将选项下拉列表附加到正文,在这种情况下,拥有overflow: hidden的父母不会有问题,但是我们需要跟踪多个事件,这些事件可能会更改select元素的位置/大小(滚动,这可以是选择框的任何父元素,调整大小,将选择元素隐藏在可滚动元素内等),这似乎既难以管理,又需要实时跟踪许多内容,可能会导致性能问题。 / li>

我的问题是,由于浏览器支持html / css / javascript的最新状态,是否有一种新的方式来处理这些以前没有的问题?也许除了我上面指出的以外,还有其他选择。

Fiddle explaining the two cases

1 个答案:

答案 0 :(得分:0)

我的意思的基本示例。

我们在屏幕上还有更多选择,因此 虚假选择将溢出其父对象,同时还会溢出屏幕底部。

您可以检查此处缺少的内容来解决您的问题吗?

const dropdown = document.querySelector( '.select' );
const selected = document.querySelector( '.selected' );
const default_text = '... Select options ...';
dropdown.addEventListener( 'click', event => {
  const classes = event.target.classList;
  if ( classes.contains( 'option' )) {
    // clicked first element
    // open the dropdown.
    // update the label if needed.
    if ( classes.contains( 'selected' )) {
      dropdown.classList.toggle( 'active' );
      if ( selected.innerHTML !== default_text ) selected.innerHTML = default_text;
    }
    // clicked other element
    // close the dropdown
    // update the label
    else {
      dropdown.classList.remove( 'active' );
      selected.innerHTML = event.target.innerHTML;
    }
  }
});
* {
  margin: 0;
  padding: 0;
}
.container {
  background-color: yellow;
  margin: 2rem;
  overflow: hidden;
  padding: 2rem;
}
.select {
  list-style: none;
  height: 22px; /* 20px + 2px borders */
  overflow: hidden;
  position: absolute;
  z-index: 1;
}
.select.active {
  overflow: visible;
}
.option {
  background-color: #EEEEEE;
  border: 1px solid black;
  border-top: none;
  height: 20px;
}
.selected {
  border-top: 1px solid black;
}
label,
input {
  background-color: #EEEEEE;
  border: 1px solid black;
  margin: 4px;
}
<section class="container">
  <label>Name:</label>
  <input type="text" value="">
  <ul class="select">
    <li class="option selected">... Select options ...</li>
    <li class="option">1</li>
    <li class="option">2</li>
    <li class="option">3</li>
    <li class="option">4</li>
    <li class="option">5</li>
    <li class="option">6</li>
    <li class="option">7</li>
    <li class="option">8</li>
    <li class="option">9</li>
    <li class="option">10</li>
    <li class="option">11</li>
    <li class="option">12</li>
    <li class="option">13</li>
    <li class="option">14</li>
    <li class="option">15</li>
    <li class="option">16</li>
    <li class="option">17</li>
    <li class="option">18</li>
    <li class="option">19</li>
    <li class="option">20</li>
    <li class="option">21</li>
    <li class="option">22</li>
    <li class="option">23</li>
    <li class="option">24</li>
    <li class="option">25</li>
  </ul>
  <label>Value:</label>
  <input type="text" value="">
</section>