在可滚动容器中定位绝对下拉列表

时间:2018-01-09 15:56:06

标签: javascript jquery html css

是否可以使位置绝对下拉列表保持在可滚动容器的顶部,并在滚动时与位置相对父级一起移动?现在,下拉列表出现在可滚动区域内。

下面的屏幕截图是我想要实现的。如果需要,我也愿意接受JavaScript解决方案。

enter image description here

jsFiddle

.navbar {
  padding-left: 0;
  white-space: nowrap;
  overflow: auto;
}

.navbar-item {
  position: relative;
  margin-left: 0;
  list-style: none;
  display: inline-block;
  width: 200px;
  text-align: center;
  border: 1px solid;
}

.dropdown {
  position: absolute;
  padding-left: 0;
  width: 200px;
  box-shadow: 0 1px 0 1px black;
  display: none;
}

.dropdown-item {
  margin-left: 0;
  list-style: none;
}

.navbar-item:hover .dropdown {
  display: block;
}
<ul class="navbar">
  <li class="navbar-item">
    <a>Item A</a>
    <ul class="dropdown">
      <li class="dropdown-item">Sub Item A</li>
      <li class="dropdown-item">Sub Item B</li>
      <li class="dropdown-item">Sub Item C</li>
    </ul>
  </li>
  <li class="navbar-item"><a>Item B</a></li>
  <li class="navbar-item"><a>Item C</a></li>
  <li class="navbar-item"><a>Item D</a></li>
  <li class="navbar-item"><a>Item E</a></li>
</ul>

2 个答案:

答案 0 :(得分:3)

一种简单的方法是使下拉列表的位置固定,但请确保相应地应用左侧和顶部值。另一种方法是将下拉菜单附加到ul元素之外,所以当它出现时它不会被包裹在其中。

.dropdown {
  position: fixed;
}

&#13;
&#13;
.navbar {
  padding-left: 0;
  white-space: nowrap;
  overflow: auto;
}

.navbar-item {
  position: relative;
  margin-left: 0;
  list-style: none;
  display: inline-block;
  width: 200px;
  text-align: center;
  border: 1px solid;
}

.dropdown {
  position: fixed;
  background-color: #fff;
  padding-left: 0;
  width: 200px;
  box-shadow: 0 1px 0 1px black;
  display: none;
}

.navbar-item {
  margin-left: 0;
  list-style: none;
}

.navbar-item:hover .dropdown {
  display: block;
}
&#13;
<ul class="navbar">
  <li class="navbar-item">
    <a>Item A</a>
    <ul class="dropdown">
      <li class="dropdown-item">Sub Item A</li>
      <li class="dropdown-item">Sub Item B</li>
      <li class="dropdown-item">Sub Item C</li>
    </ul>
  </li>
  <li class="navbar-item"><a>Item B</a></li>
  <li class="navbar-item"><a>Item C</a></li>
  <li class="navbar-item"><a>Item D</a></li>
  <li class="navbar-item"><a>Item E</a></li>
</ul>
&#13;
&#13;
&#13;

修改

我添加了一个不使用固定位置的代码段。它根据父偏移量在打开时更改其坐标。

&#13;
&#13;
$('#menu1, #submenu1').mouseover(function(event) {
  $('#submenu1').addClass("show").css($('#menu1').offset());
});

$('#menu1, #submenu1').mouseleave(function(event) {
  $('#submenu1').removeClass("show");
});
&#13;
.navbar {
  padding-left: 0;
  white-space: nowrap;
  overflow: auto;
}

.navbar-item {
  position: relative;
  margin-left: 0;
  list-style: none;
  display: inline-block;
  width: 200px;
  text-align: center;
  border: 1px solid;
}

.dropdown {
  position: absolute;
  padding-left: 0;
  width: 200px;
  box-shadow: 0 1px 0 1px black;
  display: none;
}

.dropdown.show {
  display: block;
  margin-left: 1px;
  background-color: #fff;
}

.dropdown-item {
  margin-left: 0;
  list-style: none;
}

.navbar-item:hover .dropdown {
  display: block;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="navbar">
  <li id="menu1" class="navbar-item">
    <a>Item A</a>
  </li>
  <li class="navbar-item"><a>Item B</a></li>
  <li class="navbar-item"><a>Item C</a></li>
  <li class="navbar-item"><a>Item D</a></li>
  <li class="navbar-item"><a>Item E</a></li>
</ul>

<ul id="submenu1" class="dropdown">
  <li class="dropdown-item">Sub Item A</li>
  <li class="dropdown-item">Sub Item B</li>
  <li class="dropdown-item">Sub Item C</li>
</ul>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

这是使用jQuery的选项。

基本上,正如其他人所提到的那样,你必须将subnav项目移到主导航包装器之外,这样它们就不会被隐藏。

我们可以将它们放在与主导航包装器具有类似标记的自己的包装器中,然后使用数据元素将它们匹配以允许在单击时显示/隐藏。

然后,当我们滚动主导航栏时,我们可以将subnav包装器同步到该元素的滚动位置,因此subnav项目似乎固定为主要导航项。

最后,我们可以使用CSS隐藏subnav包装器的滚动条。

下面的代码段可以为您提供一般概念,然后您可以根据需要设置样式,使其看起来更像主要和辅助导航项目的连接。

单击主导航中的导航项,然后滚动到侧面以查看其实际操作:

&#13;
&#13;
$(function(){
	var navbar = $('.navbar');
  var subnavBar = $('.subnavs-wrapper .scrollbar-hider');

  $(navbar).find('li').each(function(){
    var dataId = $(this).attr('data-id');
    var matchingUl = $(this).parent().next().find('ul[data-id="' + dataId + '"]');
    $(this).on('click', function(){
      $(matchingUl).css('visibility') == 'hidden' ?
      $(matchingUl).css('visibility', 'visible') : $(matchingUl).css('visibility', 'hidden');
    });
    
		$(navbar).on('scroll', function(){
      $(subnavBar).scrollLeft($(this).scrollLeft());
    });
	});
});
&#13;
.navbar {
  padding-left: 0;
  white-space: nowrap;
  overflow: auto;
  display: flex;
}

.navbar-item {
  position: relative;
  margin-left: 0;
  list-style: none;
  flex-shrink: 0;
  width: 200px;
  text-align: center;
  border: 1px solid;
}

.dropdown {
  position: absolute;
  padding-left: 0;
  width: 200px;
  box-shadow: 0 1px 0 1px black;
  display: none;
}

.navbar-item {
  margin-left: 0;
  list-style: none;
}

.navbar-item:hover .dropdown {
  display: block;
}

.subnavs-wrapper {
  overflow: hidden; /* hide scrollbar */
}

.subnavs-wrapper .scrollbar-hider {
  display: flex;
  overflow: auto;
  padding-bottom: 50px; /* hide scrollbar */
  margin-bottom: -50px; /* hide scrollbar */
}

.subnav {
  width: 200px;
  padding-left: 0;
  list-style: none;
  visibility: hidden;
  flex-shrink: 0;
  border: 1px solid black;
}
&#13;
<ul class="navbar">
  <li class="navbar-item" data-id="one"><a>Item A</a>
  <li class="navbar-item" data-id="two"><a>Item B</a></li>
  <li class="navbar-item" data-id="three"><a>Item C</a></li>
  <li class="navbar-item" data-id="four"><a>Item D</a></li>
  <li class="navbar-item" data-id="five"><a>Item E</a></li>
</ul>
<div class="subnavs-wrapper">
  <div class="scrollbar-hider">
    <ul class="subnav" data-id="one">
      <li>Sub Item A.A</li>
      <li>Sub Item A.B</li>
      <li>Sub Item A.C</li>
    </ul>
    <ul class="subnav" data-id="two">
      <li><a>Sub Item B.A</a></li>
    </ul>
    <ul class="subnav" data-id="three">
      <li><a>Sub Item C.A</a></li>
      <li><a>Sub Item C.B</a></li>
    </ul>
    <ul class="subnav" data-id="four">
      <li><a>Sub Item D.A</a></li>
      <li><a>Sub Item D.B</a></li>
    </ul>
    <ul class="subnav" data-id="five">
      <li><a>Sub Item E.A</a></li>
      <li><a>Sub Item E.B</a></li>
    </ul>
  </div>
</div>

<script
  src="https://code.jquery.com/jquery-3.2.1.min.js"
  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
  crossorigin="anonymous"></script>
&#13;
&#13;
&#13;