javascript - 以相对方式绝对定位 n 个孩子?
问题描述
我目前正在处理一个自定义下拉列表,我希望父级在页面内相对定位。然后我希望下拉列表的所有子项(列表项)被页面的其余部分忽略以模拟一个select
元素。我的第一个想法是通过类似于以下伪代码的方式使用 JavaScript 定位孩子:
function positionChildren() {
var ddl = document.getElementById("myDDL");
var items = ddl.getElementsByTagName("LI");
var bottom = 0;
for (var i = 0; i < items.length; i++) {
items[i].style.top = bottom + 5 + "px";
bottom += items[i].height;
}
}
父母将拥有的地方position: relative
,每个孩子都会拥有position: absolute
,因此将被那里的其余内容忽略。
不过,我不仅觉得没那么简单,而且我也相信用纯CSS大概有办法做到,所以特地来高手所在的地方求助。
到目前为止,为了清楚起见,这是我所拥有的:
function openDropDown(dropDownList) {
dropDownList.classList.toggle("selecting");
}
* {
transition: 0.3s all linear;
}
html,
body {
margin: 0;
height: 100%;
background-color: #319;
background-image: linear-gradient(45deg, #b0a, #319);
background-image: -webkit-linear-gradient(45deg, #b0a, #319);
overflow: hidden;
}
.primary-content {
height: 100%;
text-align: center;
padding: 15px;
color: #fff;
overflow-y: auto;
display: flex;
flex-direction: column;
align-items: center;
}
/* DDL Specific Styles Start Here */
.drop-down-list {
position: relative;
list-style-type: none;
padding: 0;
padding-right: 5px;
min-width: 300px;
text-align: left;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
overflow-y: auto;
overflow-x: hidden;
}
.drop-down-list:after {
content: "\21AC";
position: absolute;
top: -5px;
right: 5px;
font-size: 30px;
color: #555;
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.drop-down-list.selecting:after {
-webkit-transform: scaleX(-1) rotate(90deg);
transform: scaleX(-1) rotate(90deg);
}
.drop-down-list.selecting {
max-height: 60%;
overflow-y: auto;
}
.drop-down-list > li {
background-color: rgba(255, 255, 255, 0.95);
color: #555;
padding: 2px;
padding-left: 10px;
margin-bottom: 5px;
border-radius: 5px;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.25);
cursor: pointer;
}
.drop-down-list > li.selected {
background-color: rgba(20, 200, 255, 0.95);
color: #fff;
}
.drop-down-list:not(.selecting) > li.selected {
background-color: rgba(255, 255, 255, 0.95);
color: #555;
}
.drop-down-list:not(.selecting) > li.selected:hover {
background-color: #fff;
}
.drop-down-list:not(.selecting) > li:not(.selected) {
height: 0;
line-height: 0;
font-size: 0;
padding: 0;
margin: 0;
opacity: 0;
}
.drop-down-list > li:hover {
background-color: #fff;
}
.drop-down-list > li.selected:hover {
background-color: #3cf;
}
<div id="primary-content" class="primary-content">
<p class="lead">Click the option to expand the children out.</p>
<ul class="drop-down-list" onclick="openDropDown(this);">
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
<li class="selected">Option 4</li>
<li>Option 5</li>
<li>Option 6</li>
<li>Option 7</li>
<li>Option 8</li>
<li>Option 9</li>
<li>Option 10</li>
<li>Option 11</li>
<li>Option 12</li>
<li>Option 13</li>
</ul>
<p class="lead">This paragraph is to simulate content below the drop down to ensure that page content isn't pushed around when the control expands.</p>
</div>
如何相对于父级定位下拉列表的所有子级,但页面的其余部分会忽略它们?
- 结果必须是跨浏览器兼容的。
- 我支持 IE、Edge、Firefox、Chrome 和 Safari。
- 我可以手动添加对浏览器的支持,但接受的答案至少必须能够扩展。
- 例如,如果我支持的任何浏览器都不支持某个功能(例如
position: sticky
IE 不支持),那么我不能使用该功能,因此答案也不应该。
- 首选纯 CSS。
- 如果没有纯 CSS 解决方案,JavaScript 将被接受。
解决方案
你几乎就在那里 - 你基本上只需要一个包装在你的ul
.
一些注意事项:
进行选择将始终关闭下拉菜单。
e.stopPropagation()
如果你想解决这个问题,你需要使用下拉菜单可以离开页面底部。玩
ul
' 的高度并让它在打开时滚动应该会有所帮助下拉菜单根本无法访问
function openDropDown(dropDownList) {
dropDownList.classList.toggle("selecting");
}
* {
transition: 0.3s all linear;
}
html,
body {
margin: 0;
height: 100%;
background-color: #319;
background-image: linear-gradient(45deg, #b0a, #319);
background-image: -webkit-linear-gradient(45deg, #b0a, #319);
overflow: hidden;
}
.primary-content {
height: 100%;
text-align: center;
padding: 15px;
color: #fff;
overflow-y: auto;
display: flex;
flex-direction: column;
align-items: center;
}
/* DDL Specific Styles Start Here */
.drop-down {
width: 300px;
height: 3em;
}
.drop-down-list {
position: relative;
list-style-type: none;
padding: 0;
padding-right: 5px;
min-width: 300px;
text-align: left;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.drop-down-list:after {
content: "\21AC";
position: absolute;
top: -5px;
right: 5px;
font-size: 30px;
color: #555;
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.drop-down-list.selecting:after {
-webkit-transform: scaleX(-1) rotate(90deg);
transform: scaleX(-1) rotate(90deg);
}
.drop-down-list.selecting {
max-height: 60%;
position: absolute;
}
.drop-down-list > li {
background-color: rgba(255, 255, 255, 0.95);
color: #555;
padding: 2px;
padding-left: 10px;
margin-bottom: 5px;
border-radius: 5px;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.25);
cursor: pointer;
}
.drop-down-list > li.selected {
background-color: rgba(20, 200, 255, 0.95);
color: #fff;
}
.drop-down-list:not(.selecting) > li.selected {
background-color: rgba(255, 255, 255, 0.95);
color: #555;
}
.drop-down-list:not(.selecting) > li.selected:hover {
background-color: #fff;
}
.drop-down-list:not(.selecting) > li:not(.selected) {
height: 0;
line-height: 0;
font-size: 0;
padding: 0;
margin: 0;
opacity: 0;
}
.drop-down-list > li:hover {
background-color: #fff;
}
.drop-down-list > li.selected:hover {
background-color: #3cf;
}
<div id="primary-content" class="primary-content">
<p class="lead">Click the option to expand the children out.</p>
<div class="drop-down">
<ul class="drop-down-list" onclick="openDropDown(this);">
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
<li class="selected">Option 4</li>
<li>Option 5</li>
<li>Option 6</li>
<li>Option 7</li>
<li>Option 8</li>
<li>Option 9</li>
<li>Option 10</li>
<li>Option 11</li>
<li>Option 12</li>
<li>Option 13</li>
</ul>
</div>
<p class="lead">This paragraph is to simulate content below the drop down to ensure that page content isn't pushed around when the control expands.</p>
</div>
推荐阅读
- node.js - 将 node:12-alpine 与 puppeteer@1.19 一起使用的 Dockerfile 是什么?
- javascript - React/Redux 处理双向数据
- python-3.x - 如何在网格中找到 4 个连续数字的最大乘积?
- typescript - 使用 TypeScript 和 Sinon 时如何在单元测试中存根依赖项
- spring - spring @Scheduled 注释适用于本地 Websphere,但不适用于安装在服务器上的 Websphere
- tiff - 我想将我的 .tif 文件转换为 R 中的 .asc
- c# - 设计问题:需要一些关于如何构建类继承以避免重复代码的提示
- django - 当值不存在时设置一个值
- c# - MSBuild on Server errorCS0234 错误.net 4.7.2
- redis - docker-compose 中的 Redis 主从设置 - 只读从属