0

我正在制作日程安排日历。事件是水平块(Google Cal 有垂直块)。而且因为我在一个日期有很多事件,所以我希望这些事件可以堆叠在一起而不浪费任何空间,如下所示: 这就是我要的

我确实找到了插件: http:
//masonry.desandro.com/
http://isotope.metafizzy.co/
http://packery.metafizzy.co/
但我并不热衷于使用 30kb 插件来做到这一点简单的事情。

澄清一下:因为这是一个时间线,所以 div 事件不能向左/向右移动,但必须垂直适应其他 div 事件。

4

1 回答 1

0

我自己的解决方案是一个 2.6kb(已注释)的 jQuery 脚本,它使用绝对定位的事件和一个 div 作为每一行的容器。

此脚本生成随机大小的条形图。每个新栏从上到下检查每行中的空间。我使用百分比,因为这样计算柱位置与时间的关系会很容易(100% / 24h)。

结果

http://jsfiddle.net/cj23H/5/
虽然可以工作并且足够高效,但感觉很笨重。欢迎您改进。

来自我的 jsfiddle 的 jQuery 代码:

function rand() {
    return Math.floor(Math.random() * 101);
}

function get_target_row(width, left) {
    var i = 0;
    var target_found = false;

    // Loop through all the rows to see if there's space anywhere
    while (target_found === false) {

        // Define current row selector
        var target_i = '.personnel#row' + i;

        // Add row if none
        if ($(target_i).length === 0) {
            $('body').append('<div class="personnel" id="row' + i + '"></div>');
        }
        // See if there's space
        if ($(target_i).children().length === 0) {
            target_found = $(target_i);
        } else {
            var spaceFree = false;

            // Check collision for each child
            $(target_i).children().each(function () {

                // Get left and right coordinates
                var thisWidthPx = parseFloat($(this).css('width'), 10);
                var thisWidthParentPx = parseFloat($(this).parent().css('width'), 10);
                var thisWidth = (thisWidthPx / thisWidthParentPx * 100);
                var thisLeftPx = parseFloat($(this).css('left'), 10);
                var thisLeftParentPx = parseFloat($(this).parent().css('left'), 10);
                var thisLeft = (thisLeftPx / thisWidthParentPx * 100);
                var thisRight = thisLeft + thisWidth;
                var right = left + width;

                // Sexy way for checking collision
                if ((right > thisLeft && right < thisRight) || (left < thisRight && left > thisLeft) || (thisLeft > left && thisLeft < right) || (thisRight < right && thisRight > left)) {
                    spaceFree = false;
                    return false;
                } else {
                    spaceFree = true;
                }
            });

            // If no children have collided break the loop
            if (spaceFree === true) {
                target_found = $(target_i);
            }
        }
        i++;
    }

    // If after all the while loops target is still not found...
    if (target_found === false) {
        return false;
    }

    // Else, if target is found, return it.
    return target_found;
}

// Generate random bars
for (var i = 0; i < 10; i++) {
    var width = rand()/2;
    var left = rand()/2;
    var right = left + width;
    var target = get_target_row(width, left);
    target.append('<div class="block" style="width:' + width + '%;position:absolute;left:' + left + '%;background-color:rgba(' + rand() + ',' + rand() + ',' + rand() + ',0.4)" id="bar'+i+'">' + 'b' + i + '</div>');
}

CSS:

.block {
    position: absolute;
    background-color: rgba(200, 100, 100, 0.4);
    height: 32px;
}
.personnel {
    position: relative;
    float: left;
    width: 100%;
    height: 33px;
}
于 2013-11-09T11:42:35.233 回答