如何设置元素重叠滚动的样式

时间:2018-06-15 13:53:07

标签: javascript jquery html css

我正在开发一个已经存在的项目,前端非常复杂。我想介绍一个新元素,它应该是下拉列表的替代品。基本上它是divknockout绑定到集合。

我遇到的问题是,在一个页面上有几个div,其中为每个div渲染一个更复杂的结构,其中一个div是我的自定义下拉列表。问题是,当我尝试扩展下拉列表(使用jQuery将类绑定到click事件)时,我"dropdown"被渲染到div的顶部,因为内容太多且按顺序排列为了保留整个页面的外观和外观,没有好的方法可以使用overflow: visible

很好地介绍我的问题的代码片段是HERE

$('.show-dropdown').click(function() {
if ($(this).next('.render-this').hasClass('hide-me')) {
	$(this).next('.render-this').removeClass('hide-me');
  } else {
  $(this).next('.render-this').addClass('hide-me');
  }

})
td {
  position: relative;
}

#top-div {
  width: 500px;
  max-width: 500px;
border: 1px solid black;
  max-height: 100px;
  overflow-y: auto;
white-space: nowrap;
}

#bottom-div {
  width: 500px;
  max-width: 500px;
border: 1px solid black;
  max-height: 100px;
    overflow-y: auto;

}

.show-dropdown {
  width: 120px;
  height: 40px;
  background-color: green;
}

.render-this {
  position: absolute;
  bottom: 10px;
  z-index: 5;
  width: 20px;
  height: 150px;
  background-color: red;
}
.hide-me {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="top-div">
<p>
lorem ipsum lorem ipsum lorem ipsum lorem ipsumlorem ipsumlorem ipsum lorem ipsum lorem ipsum
</p>
</div>
<div id="bottom-div">
<table class="w3-table">
<tr>
  <th>Column 1</th>
  <th>Column 2</th>
  <th>Column 3</th>
  <th>Column 4</th>
  <th>Column 5</th>
  <th>Column 6</th>
</tr>
<tr>
  <td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
  <td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
  <td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
  <td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
  <td><div class="show-dropdown">></div><div class="render-this hide-me"></div></td>
  <td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
</tr>
</table>

我已经阅读了很多关于这个主题的内容。到目前为止我的结论是,如果你有溢出,它几乎是游戏结束。但是从问题HERE我看到,transform和其他CSS可能仍有可能实现某些目标。另外,我需要的是完全渲染我的下拉菜单,我还在考虑使用overflow: visible和某种JS创建的滚动条,但是还没有深入挖掘它。

3 个答案:

答案 0 :(得分:1)

您可以添加包含可滚动容器周围相对位置的包装器div,然后您的绝对定位下拉列表将绑定到该元素。正如您在example中看到的那样。

的CSS:

.position-relative {
    position: relative;
}

#top-div {
    width: 500px;
    max-width: 500px;
    border: 1px solid black;
    max-height: 100px;
    overflow-y: auto;
    white-space: nowrap;
}

#bottom-div {
    width: 500px;
    max-width: 500px;
    border: 1px solid black;
    max-height: 100px;
    overflow-y: auto;

}

.show-dropdown {
    width: 120px;
    height: 40px;
    background-color: green;
}

.render-this {
    position: absolute;
    bottom: 10px;
    z-index: 5;
    width: 20px;
    height: 150px;
    background-color: red;
}
.hide-me {
    display: none;
}

HTML:

<div class="position-relative">
    <div id="bottom-div">
        <table class="w3-table">
            <tr>
                <th>Column 1</th>
                <th>Column 2</th>
                <th>Column 3</th>
                <th>Column 4</th>
                <th>Column 5</th>
                <th>Column 6</th>
            </tr>
            <tr>
                <td>
                    <div class="show-dropdown"></div>
                    <div class="render-this hide-me"></div>
                </td>
                <td>
                    <div class="show-dropdown"></div>
                    <div class="render-this hide-me"></div>
                </td>
                <td>
                    <div class="show-dropdown"></div>
                    <div class="render-this hide-me"></div>
                </td>
                <td>
                    <div class="show-dropdown"></div>
                    <div class="render-this hide-me"></div>
                </td>
                <td>
                    <div class="show-dropdown">></div>
                    <div class="render-this hide-me"></div>
                </td>
                <td>
                    <div class="show-dropdown"></div>
                    <div class="render-this hide-me"></div>
                </td>
            </tr>
        </table>
    </div>
</div>

JS

$('.show-dropdown').click(function() {
    if ($(this).next('.render-this').hasClass('hide-me')) {
        $(this).next('.render-this').removeClass('hide-me');
    } else {
        $(this).next('.render-this').addClass('hide-me');
    }
})

然后您可以根据需要调整顶部,左侧,右侧,底部属性。

答案 1 :(得分:1)

如果您按照以下方式更改CSS,则可以按照需要进行操作:

  • 从您的position:relative;中删除td
  • 使用另一种方法,使用#bottom-div使display: table;扩展到其内容,并对其应用position:relative;
  • 所有其他CSS规则保持不变。

所以,这是您的新CSS:

#top-div {
  width: 500px;
  max-width: 500px;
border: 1px solid black;
  max-height: 100px;
  overflow-y: auto;
white-space: nowrap;
}

#bottom-div {
  width: 500px;
  max-width: 500px;
  border: 1px solid black;
  max-height: 100px;
  position: relative;
  display: table;
}

.show-dropdown {
  width: 120px;
  height: 40px;
  background-color: green;
}

.render-this {
  position: absolute;
  bottom: 10px;
  z-index: 5;
  width: 20px;
  height: 150px;
  background-color: red;
}
.hide-me {
  display: none;
}

这是新CSS指向Fiddle的链接。

答案 2 :(得分:1)

演示

https://jsfiddle.net/mg8zbr41/172/

(我希望这是理想的行为)

说明

如果允许我们将overflow-x: autooverflow-y: visible在一起,那么整个问题都将得到解决。但是我们不能这样做(请参见this答案)。因此,我们使用以下解决方法。

  1. 如果您想让红色div弹出,则不能放 position: relative个父级。所以我们先删除
  2. 现在bottom相对于父级相对元素(即body)而言,但我们不希望这样做,因此我们也删除了bottom
  3. 现在我们拥有toprightbottomleftauto。因此,将元素放置在绿色框下面,就像是static一样。唯一的不同是它从底部框弹出
  4. 现在我们希望它比我们使用translateY(calc(100% + 10px) * -1)的绿色框高10像素
  5. 现在这可以工作到没有滚动为止。滚动div时,红色框停留在该位置,并且不随其绿色框移动,我们需要对其进行修复
  6. 如果我们知道div滚动了多少,则可以很容易地解决此问题。假设div向左滚动100px,我们将红色框向左滚动100px
  7. 没有JS,我们找不到scrollLeft。我个人不喜欢使用JS进行样式设置。我们无法避免,但是至少可以通过使用css变量在JS和CSS之间进行通信来使其更具语义。
  8. 我们使用JS用--scroll-left值更新#bottom-div上的scrollLeft css变量
  9. 有了--scroll-left之后,我们现在可以添加translateX(calc(var(--scroll-left,0px) * -1))
  10. 我们也不希望红色框水平弹出。我们无法通过overflow: hidden来解决此问题,因为这将需要position: relative。因此,我们使用clip-path: inset(-999px 0px -999px 0px)
  11. 最后,我们实现了想要的愿望。 ew。

缺点:

  1. 由于Scroll Lined Effects,在Firefox中水平重新定位会比较缓慢。在移动浏览器中可能也是同样的问题

另请参见:

https://css-tricks.com/popping-hidden-overflow/我的答案的灵感来源,但两者(本文中的解决方案和我的解决方案)都大相径庭,但核心方法相同