我有一个div集合,这些div可以根据起始值和结束值通过JavaScript进行绝对定位和调整。
var posts = [
{
start: 50,
end: 200,
text: "Lorem ipsum"
},
{
start: 280,
end: 350,
text: "dolor"
},
{
start: 140,
end: 300,
text: "sit amet"
},
{
start: 440,
end: 590,
text: "consectetur"
},
{
start: 460,
end: 570,
text: "adipiscing"
},
{
start: 480,
end: 550,
text: "elit"
},
];
$.each(posts, function(i, post){
var obj = $("<div />");
obj.css({
left: post.start,
width: post.end - post.start
})
obj.text(post.text);
obj.appendTo("#timeline");
})
body {
font-family: Montserrat, Arial, sans-serif;
}
.timeline {
margin: 20px 0;
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
position: relative;
height: 60px;
}
.timeline div {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
height: 50px;
top: 5px;
background: darkblue;
color: #fff;
border-radius: 6px;
padding: 0 10px;
box-shadow: 0 0 0 2px #fff;
}
h1 {
font-size: 18px;
text-transform: uppercase;
color: #999;
font-weight: 400;
letter-spacing: 0.05em;
margin: 50px 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Current</h1>
<div id="timeline" class="timeline"></div>
<h1>Ideal</h1>
<!-- Height of the timeline adjusted to make room -->
<div class="timeline" style="height: 170px">
<div style="left: 50px; width: 150px;">Lorem ipsum</div>
<!-- This one not moved down because
there is still room for it in the
original position -->
<div style="left: 280px; width: 70px;">dolor</div>
<!-- Element moved down to
since it overlaps two previous ones -->
<div style="left: 140px; width: 160px; top: 60px;">sit amet</div>
<div style="left: 440px; width: 150px;">consectetur</div>
<!-- Element moved down -->
<div style="left: 460px; width: 110px; top: 60px;">adipiscing</div>
<!-- Element moved down even further -->
<div style="left: 480px; width: 70px; top: 115px;">elit</div>
</div>
但是,如果两个或更多个div的起始值和结束值重叠,则生成的div也将重叠。理想情况下,我想计算哪些div会重叠,并添加一个top
值,以便每个div都完全可见。 start
值较大的元素应该是向下移动的元素。
如何确定哪些元素重叠,以便将这些元素向下移一两个凹口?
答案 0 :(得分:1)
这是一种比较幼稚的方法,它只是循环浏览所有帖子,并对照其他帖子检查每个帖子。如果发现它们在相同范围内,则会增加最高值。仅在帖子具有相同的最高值时,才会进行比较。
请注意,此方法的运行时间为O(n ^ 2),虽然不是很大,但对于少量发布,应该没问题。
function detectOverlaps(posts) {
for (let i=0; i<posts.length; i++) {
for (let j=0; j<posts.length; j++) {
if (i == j) continue;
var post1 = posts[i];
var post2 = posts[j];
if (post1.top != post2.top) continue;
if ((post1.start < post2.end && post1.start > post2.start) ||
(post1.end > post2.start && post1.end < post2.end)) {
var post = (post1.start>post2.start) ? post1 : post2;
if (!post.top) post.top = 0;
post.top += 60; // Change this by the pixel amount
}
}
}
return posts;
}
答案 1 :(得分:0)
跟踪每行实际插入的内容,然后可以运行一个简单的check-overlap函数来确定下一个div是否适合:
var posts = [
{
start: 50,
end: 200,
text: "Lorem ipsum"
},
{
start: 280,
end: 350,
text: "dolor"
},
{
start: 140,
end: 300,
text: "sit amet"
},
{
start: 440,
end: 590,
text: "consectetur"
},
{
start: 460,
end: 570,
text: "adipiscing"
},
{
start: 480,
end: 550,
text: "elit"
},
];
var lines = [];
$.each(posts, function(i, post){
var obj = $("<div />");
var lineNumber = addToLines(lines, post);
if (lineNumber === lines.length) {
lines.push([post]);
}
obj.css({
left: post.start,
width: post.end - post.start,
top: 3 + lineNumber * 54
})
obj.text(post.text);
obj.appendTo("#timeline");
})
function addToLines(lines, post)
{
for (var i = 0; i < lines.length; i++){
if (fitsInLine(lines[i], post)) {
lines[i].push(post);
return i;
}
};
return i;
}
function fitsInLine(line, postToAdd)
{
for (var i = 0; i < line.length; i++){
if (overlaps(postToAdd, line[i])) return false;
}
return true;
}
function overlaps(x, y)
{
if (x.start < y.end && x.start > y.start) return true;
if (x.end < y.end && x.end > y.start) return true;
return false;
}
body {
font-family: Montserrat, Arial, sans-serif;
}
.timeline {
margin: 20px 0;
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
position: relative;
height: 180px;
}
.timeline div {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
height: 50px;
top: 5px;
background: darkblue;
color: #fff;
border-radius: 6px;
padding: 0 10px;
box-shadow: 0 0 0 2px #fff;
}
h1 {
font-size: 18px;
text-transform: uppercase;
color: #999;
font-weight: 400;
letter-spacing: 0.05em;
margin: 50px 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Current</h1>
<div id="timeline" class="timeline"></div>
<h1>Ideal</h1>
<!-- Height of the timeline adjusted to make room -->
<div class="timeline" style="height: 170px">
<div style="left: 50px; width: 150px;">Lorem ipsum</div>
<!-- This one not moved down because
there is still room for it in the
original position -->
<div style="left: 280px; width: 70px;">dolor</div>
<!-- Element moved down to
since it overlaps two previous ones -->
<div style="left: 140px; width: 160px; top: 60px;">sit amet</div>
<div style="left: 440px; width: 150px;">consectetur</div>
<!-- Element moved down -->
<div style="left: 460px; width: 110px; top: 60px;">adipiscing</div>
<!-- Element moved down even further -->
<div style="left: 480px; width: 70px; top: 115px;">elit</div>
</div>