javascript-在不滚动容器的情况下将内容移至视图

时间:2019-02-09 20:35:03

标签: javascript html css

我们的购物网站上有一个包含主要类别和子类别的下拉菜单。将鼠标悬停在主要类别上时,子类别菜单会在右侧弹出。问题是两个菜单都包含在同一个滚动容器中。因此,您向下滚动以在当前视口下找到一个主要类别,将鼠标悬停在一个主要类别上,并且子类别会在左侧弹出,但是您已向下滚动,因此您只会看到一部分子类别。因此,我们当前无法解决的修复方法是将容器滚动到子类别的顶部,这也是类别的顶部。因此,现在您的鼠标位于不同的类别上,并且弹出了不同的子类别集。因此,基本上您不能在视口下查看类别的子类别。理想情况下,我们将使用单独的滚动条使它们成为单独的容器。但这看起来一点也不好,也不可接受。

注意:仅当浏览器窗口高度缩小到足以引起垂直滚动条时,才会发生这种情况。显然,如果窗口足够大,则不需要滚动条,也没有问题。

这是当前的样子。将鼠标悬停在“电气”类别上,该子类别会在右侧弹出。 enter image description here

我们使用的是javascript和vue.js,没有jquery。我了解到这段代码会将子类别菜单滚动到视图中,这不是我们想要的。

var el = document.querySelector('.nav-flyout-menu');
      el.scrollIntoView(true);

我想我想要的是实际移动,就像在子类别菜单的set style.top到当前视口的顶部一样。我玩了一点儿,什么也做不了。有谁知道我们如何成功解决这个问题。动态设置style.top是最好的方法吗?我该如何设置呢?我已经尝试过这样的事情:

var topBound = document.querySelector('.nav-flyout-menu').getBoundingClientRect().top;
if(topBound < 0) {
  let newTop = Math.abs(topBound) + 42;
  document.querySelector('.nav-flyout-menu').style.top = newTop + "px";
}

此代码有时有效,有时无效。

更新:根据要求,这是我创建的fiddle,用于展示我的问题。它与我们的网站不完全一样,但我认为它已经足够接近了。使示例高度足够小,以强制滚动条并将鼠标悬停在每个类别上。向下滚动以查看底部类别时,将无法看到子类别的顶部。这正是我们当前面临的问题。我想在显示当前子类别时更改top值。但我不知道如何计算该最高价值。我使用jQuery只是为了提起小提琴示例,但我们不在网站上使用jQuery。

$("a.dropdown-item").hover(
	function () {
    $(".nav-flyout-menu").removeClass("show");
    let category = $.trim($(this).text());
    category = category.replace(/\s+/g, '-').toLowerCase();
    $("." + category).addClass("show");
  }, 
  function () {
    
  }
)
.navbar {
  width: 100%;
  display: flex;
  position: relative;
  padding: 0.5rem 1rem;
  background-color: #0000cc;
  flex-direction: row;
}
.navbar a {
  color: #ffffff;
}
.navbar .dropdown-menu a {
  color: #000000;
}
ul {
  list-style: none;
}

.dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 1000;
  display: block;
  float: left;
  min-width: 10rem;
  padding: .5rem 0;
  margin: 0;
  font-size: 1rem;
  color: #212529;
  text-align: left;
  list-style: none;
  background-color: #fff;
  background-clip: padding-box;
  border: 1px solid rgba(0,0,0,.15);
  border-bottom: .5rem solid #cc0000;
  padding-right: 1.5rem;
}
.navbar-nav .dropdown-menu {
    position: static;
    float: none;
}
.navbar-container .dropdown-menu {
    max-height: calc(100vh - 150px);
    overflow-y: auto;
}
.dropdown-item {
    display: block;
    width: 100%;
    padding: .5rem 1.5rem;
    clear: both;
    text-align: inherit;
    white-space: nowrap;
    background-color: transparent;
    border: 0;
}
.nav-flyout-root {
    position: relative;
    display: inline-block;
    float: left;
}
.nav-flyout-menu {
    display: none;
    flex-direction: column;
    float: left;
    min-width: 10rem;
    padding: .5rem 0;
    margin: 0;
    font-size: 1rem;
    color: #212529;
    text-align: left;
    list-style: none;
    background-color: #fff;
    background-clip: padding-box;
}
.nav-flyout-menu.show {
  display: inline-flex;
}
.flyout-menu-item {
    font-weight: 400;
    color: #212529;
    text-align: inherit;
    white-space: nowrap;
    background-color: transparent;
    border: 0;
    display: block;
    width: 100%;
    padding: .5rem 1.5rem;
    clear: both;
}
.submenu div {
  display: block;
}
.dropdown-item:focus, .dropdown-item:hover, .dropdown-item a:focus, .dropdown-item a:hover {
    color: #fff!important;
    text-decoration: none;
    background-color: #430984;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="navbar-container">
  <div class="navbar">
    <ul>
      <li>
        <a href="#">First</a>
        <div class="dropdown-menu">
          <div class="d-flex">
            <div class="nav-flyout-root">
              <a class="dropdown-item">
                Computers
              </a>
              <a class="dropdown-item">
                Laptops
              </a>
              <a class="dropdown-item">
                Monitors
              </a>
              <a class="dropdown-item">
                Hard Drives
              </a>
              <a class="dropdown-item">
                Keyboards
              </a>
              <a class="dropdown-item">
                Mice
              </a>
              <a class="dropdown-item">
                Computers
              </a>
              <a class="dropdown-item">
                Laptops
              </a>
              <a class="dropdown-item">
                Monitors
              </a>
              <a class="dropdown-item">
                Hard Drives
              </a>
              <a class="dropdown-item">
                Keyboards
              </a>
              <a class="dropdown-item">
                Mice
              </a>
            </div>
            <div class="nav-flyout-menu position-relative computers">
              <div class="flyout-menu-header text-nowrap">
                <a href="#">All Computers</a>
              </div>
              <div class="d-flex flex-grow-1 flex-column submenu">
                <div>
                  <a href="#" class="flyout-menu-item">Dell</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">HP</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Asus</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Compaq</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Dell</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Samsung</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Acer</a>
                </div>
              </div>
            </div>
            <div class="nav-flyout-menu position-relative laptops">
              <div class="flyout-menu-header text-nowrap">
                <a href="#">All Laptops</a>
              </div>
              <div class="d-flex flex-grow-1 flex-column submenu">
                <div>
                  <a href="#" class="flyout-menu-item">Acer</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">HP</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Sony</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Compaq</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Vaio</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Apple</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Acer</a>
                </div>
              </div>
            </div>
            <div class="nav-flyout-menu position-relative monitors">
              <div class="flyout-menu-header text-nowrap">
                <a href="#">All Monitors</a>
              </div>
              <div class="d-flex flex-grow-1 flex-column submenu">
                <div>
                  <a href="#" class="flyout-menu-item">Qnix</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">HP</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Sony</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Dell</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Asus</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">22"</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">23"</a>
                </div>
              </div>
            </div>
            <div class="nav-flyout-menu position-relative hard-drives">
              <div class="flyout-menu-header text-nowrap">
                <a href="#">All Hard Drives</a>
              </div>
              <div class="d-flex flex-grow-1 flex-column submenu">
                <div>
                  <a href="#" class="flyout-menu-item">Western Digital</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Samsung</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">HP</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Seagate</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Kingston</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Crucial</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">SSD</a>
                </div>
              </div>
            </div>
            <div class="nav-flyout-menu position-relative keyboards">
              <div class="flyout-menu-header text-nowrap">
                <a href="#">All Keyboards</a>
              </div>
              <div class="d-flex flex-grow-1 flex-column submenu">
                <div>
                  <a href="#" class="flyout-menu-item">Logitech</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Microsoft</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Gearhead</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Razer</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Cherry MX</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Mech Blue</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Mech Red</a>
                </div>
              </div>
            </div>
            <div class="nav-flyout-menu position-relative mice">
              <div class="flyout-menu-header text-nowrap">
                <a href="#">All Mice</a>
              </div>
              <div class="d-flex flex-grow-1 flex-column submenu">
                <div>
                  <a href="#" class="flyout-menu-item">Steel Series</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Microsoft</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Logitech</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Razer</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Cooler Master</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">HyperX</a>
                </div>
                <div>
                  <a href="#" class="flyout-menu-item">Roccat</a>
                </div>
              </div>
            </div>
          </div>
        </div>
      </li>
    </ul>
  </div>
</div>

2 个答案:

答案 0 :(得分:1)

您可以将一个类添加到活动子菜单元素

var el = document.querySelector('.nav-flyout-menu');
el.classList.add("nav-active-sub-menu");

并使用CSS控制其样式。像这样:

.nav-active-sub-menu{
    position: absolute;
    top: 0;
}

让我知道你的意思吧。

祝你好运!

答案 1 :(得分:0)

最后得到了!我知道必须使用一些简单的javascript才能实现。我是对的。 Element.scrollTop是关键。我认为仅凭CSS不可能做到这一点,如果我错了,有人可以纠正我。 我们有一个事件侦听器,用于悬停主菜单项以显示子菜单。在该侦听器中,我输入了以下代码:

let scrollTop = vm.$el.parentElement.parentElement.parentElement.scrollTop;
document.querySelector('.nav-flyout-menu').style.top = scrollTop + "px";

这似乎在我所有的测试中都有效。