简体   繁体   English

如何使绝对定位的元素彼此不重叠?

[英]How can I make absolute positioned elements not overlapping each other?

Here is what I want to do: I'm using gridster in order to create a form creation IDE. 这是我想做的事情:我正在使用gridster来创建表单创建IDE。 The user drags elements in the grid, and can move them around. 用户可以在网格中拖动元素,并可以在其中移动元素。

Everything works great inside the editor, but when I try to use those forms but I'm having issues when the elements inside the grid positions become bigger than the grid block that contains them, making one element overlapping another. 一切都在编辑器中运行良好,但是当我尝试使用这些表单时,当网格位置内的元素变得大于包含它们的网格块,从而使一个元素与另一个元素重叠时,我遇到了问题。

What I'm looking for is an automated solution that when given a bunch of absolute positioned elements, it moves them up or down so they don't overlap. 我正在寻找的是一种自动化解决方案,当给定一堆绝对定位的元素时,它会将它们上下移动,以免它们重叠。 Does such thing exist? 这样的东西存在吗?

The whole point of absolute positioning is that it overrides the clients ability to reflow the layout. 绝对定位的全部要点是它覆盖了客户重新布局的能力。 What you're asking for is directly in conflict with the purpose of absolute positioning. 您要的是与绝对定位的目的直接冲突。

Theoretically, you could run some javascript everytime something changes and recalculate all the layouts and move things around, but that's a lot of work to do it right. 从理论上讲,您可以在每次发生更改时运行一些javascript,然后重新计算所有布局并四处移动,但这要做好很多工作。

You would probably also conflict with Gridster's code as well. 您可能还会与Gridster的代码冲突。 So you would need to take that into account, and possibly even require rewriting Gridster code. 因此,您需要考虑到这一点,甚至可能需要重写Gridster代码。

I made a workaround myself 我自己做了一个解决方法

I wrote this code, and put it inside an interval that loops all the time, making the elements that belong to the same column not overlapping. 我编写了这段代码,并将其放在始终循环的时间间隔内,使属于同一列的元素不重叠。

Take note that the .gs_w is the class of the gridster grid cell which contains the .form_row which in turn contains the input element itself and shrinks to fit it. 请注意, .gs_w是gridster网格单元格的类,该单元格包含.form_row ,而后者又包含输入元素本身并缩小以适合它。

Finally this won't work if dragging is enabled, which in my case is ok because only the form editor I built utilises dragging. 最后,如果启用了拖动,这将不起作用,在我看来,这是可以的,因为只有我构建的表单编辑器才使用拖动。 Not the forms themselves. 不是表格本身。

setInterval(collision_checks);

/**
 * Handles vertical collisions of gridster elements
 */
function collision_checks()
{
    var elements = $('.gs_w');
    if(!$(elements).length)
    {
        return;
    }

    var columns = {};
    // Group the elements in columns
    $(elements).each(function(){
        //If an element takes more than one columns, add it in all of them
        //so collision gets handled properly
        for(var i = 0; i < $(this).data('sizex'); i++)
        {
            columns[parseInt($(this).data('col'), 10) + i] = columns[parseInt($(this).data('col'), 10) + i] || [];
            columns[parseInt($(this).data('col'), 10) + i].push(this);
        }

    });

    // For each column, handle if it's elements collides with the element below it
    for(var i in columns)
    {
        if(!columns.hasOwnProperty(i)){continue;}
        var column = columns[i];
        for(var j in column)
        {
            if(!column.hasOwnProperty(j)){continue;}
            var element = column[j];
            var element_below = column[parseInt(j,10) + 1];

            if(!$(element).is(':visible'))
            {
                continue;
            }

            if(element == element_below)
            {
                continue;
            }

            var depth = penetration_depth(element, element_below);
            if(depth)
            {
                var offset = $(element_below).position();
                $(element_below).css('top', offset.top + depth);
            }
        }
    }
}


/**
 * if the top element overlaps the bottom one, this function returns their penetration depth
 */
function penetration_depth(el_top, el_bottom)
{
    if(!el_bottom){return 0;}
    if($(el_top).find('.form_row').offset().top + $(el_top).find('.form_row').outerHeight(true) > $(el_bottom).find('.form_row').offset().top)
    {
        return $(el_top).find('.form_row').offset().top + $(el_top).find('.form_row').outerHeight(true) - $(el_bottom).find('.form_row').offset().top;
    }
    else
    {
        return 0;
    }
}

Any suggestions or improvements are welcome! 欢迎任何建议或改进!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM