在弹性项目之间显示一个 div
Posted
技术标签:
【中文标题】在弹性项目之间显示一个 div【英文标题】:Show a div in between flex items 【发布时间】:2018-02-03 05:08:47 【问题描述】:我正在创建一个填充有<div>
元素的页面。包含这个 div 的容器有display: flex;
。所以项目自动换行到几行。现在我想点击一个项目,这样它会打开另一个<div>
,其中包含有关所选项目的信息。但此信息 div 应位于包含所选 div 的行下方,并且具有容器的全宽。
我不知道如何进行这项工作。 我做了一个简单的 JsFiddle 开头:https://jsfiddle.net/44j4jnq4/3/
我正在获取点击事件,并通过 Angular 动态添加 dinfo div。 我的问题主要是关于如何设置它的样式,这样它就不会弄乱弹性项目并具有容器的宽度。
我也有这张图片来形象化我的目标。
希望你能帮我解决这个问题。
【问题讨论】:
使用 Angular,您需要找到所选项目行上的最后一项,在其后注入元素并将其flex-basis
设置为 100%
。这样做之后,注入的元素将参与到您的绘图显示中的布局中,在自己的一行上填充容器的宽度。
@LGSon 但是我如何连续获得最新的弹性项目。如果信息框打开并且我调整页面大小,那么这会起作用吗,所以最后一个元素会翻转下一行?如果可能的话,我宁愿看到更多基于 CSS 的东西,然后用 Angualr 简单地计算它。
由于没有 CSS 会知道哪个元素是最后一个并且能够在之后保留注入的元素,因此最接近的是在单击后注入它,并且绘图作为样本,你会得到这个:jsfiddle.net/44j4jnq4/4
如果点击第二个项目,你会得到这个jsfiddle.net/44j4jnq4/5 ...并且你可以看到他们不会平均每行的项目。为了克服这个问题,您需要一个脚本来找到行中的最后一个并在它之后注入它。您还需要使用调整大小事件并跟踪换行符并相应地调整注入的项目
@LGSon 我没有在两行之间注入新的div
,而是希望扩大点击的div
的高度并将信息框添加到该div。就像在这个Fiddle 中一样,但我现在不知道如何使它成为容器的宽度。我猜这样它总是连接到正确的div。
【参考方案1】:
我通过将.item
包裹在.item-container
中来稍微修改了html 以实现所需的样式。
我还使用:after
元素来显示来自title
的.infobox
的信息。
为了填充宽度,我添加了一个高度固定的 div 和一个绝对定位的 :after
,它引用了 .container
以获取全宽,请单击 .item
以查看信息,请检查这个出来了。
$('.container').click(function(e)
if(!$(e.target).next().hasClass('show'))
$('.item-container .show').removeClass('show');
$(e.target).next().addClass('show');
)
.container
display: flex;
flex-direction: row;
flex-wrap: wrap;
background-color: grey;
position: relative;
.item
width: 300px;
height: 150px;
background-color: pink;
margin: 0px 5px 10px 5px;
.infobox
height: 110px;
display: none;
.infobox.show
display: block;
.infobox.show:after
content: attr(title);
display: block;
height: 100px;
background: #FFF;
width: calc(100% - 20px);
position: absolute;
overflow-y: scroll;
left: 0;
margin-left: 10px;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div class="container">
<div class="item-container">
<div class="item">Item 1</div><div class="infobox" title="Item 1 info"></div>
</div>
<div class="item-container">
<div class="item">Item 2</div><div class="infobox" title="Item 2 info"></div>
</div>
<div class="item-container">
<div class="item">Item 3</div><div class="infobox" title="Item 3 info"></div>
</div>
<div class="item-container">
<div class="item">Item 4</div><div class="infobox" title="Item 4 info"></div>
</div>
<div class="item-container">
<div class="item">Item 5</div><div class="infobox" title="Item 5 info"></div>
</div>
<div class="item-container">
<div class="item">Item 6</div><div class="infobox" title="Item 6 info"></div>
</div>
<div class="item-container">
<div class="item">Item 7</div><div class="infobox" title="Item 7 info"></div>
</div>
<div class="item-container">
<div class="item">Item 8</div><div class="infobox" title="Item 8 info"></div>
</div>
</div>
不使用:after
元素,试试这个
$('.container').click(function(e)
if(!$(e.target).next().hasClass('show'))
$('.item-container .show').removeClass('show');
$(e.target).next().addClass('show');
$(e.target).next().html('<div class="content"><h4>'+$(e.target).next().attr('title')+'</h4><img style="width:50px" src="https://olinuris.library.cornell.edu/sites/default/files/equipment/Draper%2050x50%20Template_1.jpg" /><button>Press</button></div>')
)
.container
display: flex;
flex-direction: row;
flex-wrap: wrap;
background-color: grey;
position: relative;
.item
width: 300px;
height: 150px;
background-color: pink;
margin: 0px 5px 10px 5px;
.infobox
height: 160px;
display: none;
.infobox.show
display: block;
.infobox .content
height: 150px;
background: #FFF;
width: calc(100% - 20px);
overflow-y: scroll;
position: absolute;
left: 0;
margin-left: 10px;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div class="container">
<div class="item-container">
<div class="item">Item 1</div><div class="infobox" title="Item 1 info"></div>
</div>
<div class="item-container">
<div class="item">Item 2</div><div class="infobox" title="Item 2 info"></div>
</div>
<div class="item-container">
<div class="item">Item 3</div>
<div class="infobox" title="Item 3 info"></div>
</div>
<div class="item-container">
<div class="item">Item 4</div><div class="infobox" title="Item 4 info"></div>
</div>
<div class="item-container">
<div class="item">Item 5</div><div class="infobox" title="Item 5 info"></div>
</div>
<div class="item-container">
<div class="item">Item 6</div><div class="infobox" title="Item 6 info"></div>
</div>
<div class="item-container">
<div class="item">Item 7</div><div class="infobox" title="Item 7 info"></div>
</div>
<div class="item-container">
<div class="item">Item 8</div><div class="infobox" title="Item 8 info"></div>
</div>
</div>
【讨论】:
缺点是由于使用了绝对定位,因此信息不会推动紧随其后的元素 如果你检查你可以看到.infobox
没有定位只有:after
元素被定位。由于父级相对于.item
,它会推送内容,唯一的限制是我们必须为.infobox
设置一个特定的高度,如果信息不是动态的,这不是问题。
这就是我所说的 info 不会推送后面的元素时的意思。这个解决方案需要在信息上设置一个固定的高度,这可能非常好,是一个纯 CSS 的解决方案
这个解决方案看起来很有希望,我想我可以在 Angular 中使用 ngIf 删除“隐藏”信息框。我会试一试,看看效果如何。
@SaravananI 我测试了你更新的代码,它可以工作。所以我想这已经解决了。谢谢你,以及所有其他人的帮助。以上是关于在弹性项目之间显示一个 div的主要内容,如果未能解决你的问题,请参考以下文章