如何在两个flex样式的行之间添加一个元素,并使下面的行根据新元素的高度向下移动

How to add an element between 2 flex-styled rows and make the row below move down based on new element height?

本文关键字:元素 新元素 移动 高度 两个 flex 样式 一个 添加 之间      更新时间:2023-09-26

请看下面这个基本的例子:

http://tympanus.net/Blueprints/ResponsiveFullWidthGrid/

现在想象一下,通过单击一个猫框,我需要(特别是在小到中等屏幕上)在被单击的猫行下面添加一个100%宽度的文本框(比如被单击的猫的描述)。该文本框应将其余行向下推。

我是一个完整的css/js/前端开发人员,但我从未遇到过这样的问题。这也是我第一次使用flexbox布局。固定的布局将是相当琐碎的,但在这种情况下,我不能想出一个好的方法来做它。例如,要解决的问题之一是:我应该把盒子放在哪里(相对于点击的盒子?),我应该通过javascript根据当前的项目每行改变位置,或者可能有一个更智能的css方式?

这是一个有趣的挑战:)

知道在哪里放置扩展区域(我称之为infoBox)的唯一方法是识别下一行的第一个节点,然后在它之前插入它。如果最后一行没有节点,我们可以将其附加到ul的末尾。

我还添加了一个窗口。resize事件处理程序,它将关闭infoBox,这样它就不会破坏响应式布局,以及一个关闭按钮。

工作示例- fiddle.

HTML是从codrop文章中复制粘贴的。

JS

var rfgrid = document.querySelector('.cbp-rfgrid');
var items = Array.from(document.querySelectorAll('.cbp-rfgrid > li'));
/** Create infoBox **/
var infoBox = document.createElement('div');
infoBox.classList.add('infoBox');
infoBox.innerHTML = '<div class="close">X</div><div class="content"></div>';
infoBoxClose = infoBox.querySelector('.close');
infoBoxContent = infoBox.querySelector('.content');
/** add close button functionality **/
infoBoxClose.addEventListener('click', function() {
    rfgrid.removeChild(infoBox);
});
/** remove infoBox on resize to maintain layout flow **/
window.addEventListener('resize', function() {
    rfgrid.removeChild(infoBox);
});
items.forEach(function (item) {
    item.addEventListener('click', function (event) {
        event.preventDefault();
        var insertReference = findReference(this); // get refence to next line 1st node
        infoBoxContent.innerHTML = items.indexOf(this); // example of changing infoBox content
        if(insertReference) {
            rfgrid.insertBefore(infoBox, insertReference); // insert infoBox before the reference
        } else {
            rfgrid.appendChild(infoBox); // insert infoBox as last child
        };
    });
});
/** find reference to 1st item of next line or null if last line **/
function findReference(currentNode) {
    var originalTop = currentNode.offsetTop; // get the clicked item offsetTop
    do {
        currentNode = currentNode.nextSibling; // get next sibling
    } while (currentNode !== null && (currentNode.nodeType !== 1 || currentNode.offsetTop === originalTop)); // keep iterating until null (last line) or a node with a different offsetTop (next line)
    return currentNode;
}

CSS(除了原来的)

.infoBox {
    position: relative;
    width: 100%;
    height: 200px;
    padding: 20px 0 0 0;
    clear: both;
    background: paleturquoise;
}
.infoBox > .close {
    position: absolute;
    top: 5px;
    right: 5px;
    cursor: pointer;
}