我正在开发一个已经存在的项目,前端非常复杂。我想介绍一个新元素,它应该是下拉列表的替代品。基本上它是div
与knockout
绑定到集合。
我遇到的问题是,在一个页面上有几个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
创建的滚动条,但是还没有深入挖掘它。
答案 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:
#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: auto
和overflow-y: visible
在一起,那么整个问题都将得到解决。但是我们不能这样做(请参见this答案)。因此,我们使用以下解决方法。
position: relative
个父级。所以我们先删除bottom
top
,right
,bottom
,left
,auto
。因此,将元素放置在绿色框下面,就像是static
一样。唯一的不同是它从底部框弹出translateY(calc(100% + 10px) * -1)
的绿色框高10像素scrollLeft
。我个人不喜欢使用JS进行样式设置。我们无法避免,但是至少可以通过使用css变量在JS和CSS之间进行通信来使其更具语义。--scroll-left
值更新#bottom-div
上的scrollLeft
css变量--scroll-left
之后,我们现在可以添加translateX(calc(var(--scroll-left,0px) * -1))
overflow: hidden
来解决此问题,因为这将需要position: relative
。因此,我们使用clip-path: inset(-999px 0px -999px 0px)
。https://css-tricks.com/popping-hidden-overflow/我的答案的灵感来源,但两者(本文中的解决方案和我的解决方案)都大相径庭,但核心方法相同