Javascript 会议日历|如何处理日历中显示的重叠会议?
很抱歉问了这么长的问题 我尝试在日历上创建一个一天的会议。我需要帮助来处理重叠的间隔 我编写的代码如下: HTMLJavascript 会议日历|如何处理日历中显示的重叠会议?,javascript,html,css,calendar,Javascript,Html,Css,Calendar,很抱歉问了这么长的问题 我尝试在日历上创建一个一天的会议。我需要帮助来处理重叠的间隔 我编写的代码如下: HTML <body> <div id="timeline"></div> <div id="calendar" class="calendar"> </div> </body> JS .calendar { border: 1px solid black; position: absolute;
<body>
<div id="timeline"></div>
<div id="calendar" class="calendar">
</div>
</body>
JS
.calendar {
border: 1px solid black;
position: absolute;
width: 600px;
height: 1440px;
left: 60px;
}
.event {
position: absolute;
float: left;
width: 100%;
overflow: auto;
border: 0px solid red;
}
#timeline {
position: absolute;
float: left;
}
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
function creatTimeline(tl) {
var i = 0;
while (i < tl.length) {
var divEl = document.createElement('div');
divEl.style.width = '50px';
divEl.style.height = '120px';
divEl.style.border = '0px solid yellow';
divEl.innerHTML = tl[i];
var timeLine = document.getElementById('timeline');
timeLine.appendChild(divEl);
i++;
}
}
function appendEventDivs(eventArr) {
var i = 0;
while (i < eventArr.length) {
var eventEl = document.createElement('div');
eventEl.className = 'event';
eventEl.style.height = eventArr[i].height;
eventEl.style.top = eventArr[i].top;
eventEl.style.background = eventArr[i].color;
eventEl.style.width = eventArr[i].width;
eventEl.style.left = eventArr[i].left;
eventEl.innerHTML = 'Meeting' + eventArr[i].id;
var cl = document.getElementById('calendar');
cl.appendChild(eventEl);
i++;
}
}
function collidesWith(a, b) {
return a.end > b.start && a.start < b.end;
}
function checkCollision(eventArr) {
for (var i = 0; i < eventArr.length; i++) {
eventArr[i].cols = [];
for (var j = 0; j < eventArr.length; j++) {
if (collidesWith(eventArr[i], eventArr[j])) {
eventArr[i].cols.push(i);
}
}
}
return eventArr;
}
function updateEvents(eventArr) {
eventArr = checkCollision(eventArr);
var arr = [];
arr = eventArr.map(function(el) {
//just to differentiate each event with different colours
el.color = getRandomColor();
el.height = (el.end - el.start) * 2 + 'px';
el.top = (el.start) * 2 + 'px';
el.width = (600 / el.cols.length) + 'px';
return el;
});
return arr;
}
var events = [{
id: 123,
start: 60,
end: 150
}, {
id: 124,
start: 540,
end: 570
}, {
id: 125,
start: 555,
end: 600
}, {
id: 126,
start: 585,
end: 660
}];
var timeline = ['9AM', '10AM', '11AM', '12Noon', '1PM', '2PM', '3PM', '4PM', '5PM', '6PM', '7PM', '8PM', '9PM'];
function getEvents (eventArr) {
eventArr.sort(function(a, b) {
return a.start - b.start;
});
eventArr = updateEvents(eventArr);
appendEventDivs(eventArr);
console.log(eventArr);
//PART 1 - function returning the eventArr with all the required attributes
return eventArr;
};
creatTimeline(timeline);
getEvents(events);
函数getRandomColor(){
变量字母='0123456789ABCDEF'。拆分('');
var color='#';
对于(变量i=0;i<6;i++){
颜色+=字母[Math.floor(Math.random()*16)];
}
返回颜色;
}
功能创建时间线(tl){
var i=0;
而(i提前感谢。您已经知道每个活动的顶部和高度,因此您可以映射日历并检查活动将占用的区域内是否已经存在活动,然后用现有事件的数量偏移左值。在确定每个事件的宽度或左位置之前,您需要确定每个事件应位于哪一列。要执行此操作,还需要存储每个事件之前发生的碰撞事件:
function checkCollision(eventArr) {
for (var i = 0; i < eventArr.length; i++) {
eventArr[i].cols = [];
eventArr[i].colsBefore=[];
for (var j = 0; j < eventArr.length; j++) {
if (collidesWith(eventArr[i], eventArr[j])) {
eventArr[i].cols.push(j);
if(i>j) eventArr[i].colsBefore.push(j); //also list which of the conflicts came before
}
}
}
return eventArr;
}
工作小提琴:
我添加了一些其他事件来测试不同的场景
哦,顺便问一下,
绝对定位元素
不能浮动
我该如何准确地用列数和偏移量制作一张地图?你能详细说明一下吗?一个小代码就太棒了:)你真是太棒了,先生!!!!非常感谢:)我会记住不要浮动绝对定位的元素:)我仍在试图弄清楚您是如何提出此解决方案的…:\哦,我的解释是不清楚还是需要详细说明?老实说,我已经准备好放弃了,在小提琴上工作了两个小时,半个小时没有保存,然后创建了一个无限循环,标签崩溃了&我的工作丢了。。。所以在这一点上,我可能已经开始放松一些评论了,哈哈。如果我有时间的话,也许明天我会研究改进我的评论。是的,我可以看到这篇文章已经做了很多工作。这是一门伟大的艺术,像我这样的普通程序员几乎不会花时间去理解它。你是摇滚明星。。。。!!!(我希望我能马上给你一个SO标签..!!!)。
function updateEvents(eventArr) {
eventArr = checkCollision(eventArr);
var arr=eventArr.slice(0); //clone the array
for(var i=0; i<arr.length; i++){
var el=arr[i];
el.color = getRandomColor();
el.height = (el.end - el.start) * 2 + 'px';
el.top = (el.start) * 2 + 'px';
if(i>0 && el.colsBefore.length>0){ //check column if not the first event and the event has collisions with prior events
if(arr[i-1].column>0){ //if previous event wasn't in the first column, there may be space to the left of it
for(var j=0;j<arr[i-1].column;j++){ //look through all the columns to the left of the previous event
if(el.colsBefore.indexOf(i-(j+2))===-1){ //the current event doesn't collide with the event being checked...
el.column=arr[i-(j+2)].column; //...and can be put in the same column as it
}
}
if(typeof el.column==='undefined') el.column=arr[i-1].column+1; //if there wasn't any free space, but it ito the right of the previous event
}else{
var column=0;
for(var j=0;j<el.colsBefore.length;j++){ //go through each column to see where's space...
if(arr[el.colsBefore[el.colsBefore.length-1-j]].column==column) column++;
}
el.column=column;
}
}else el.column=0;
}
//We need the column for every event before we can determine the appropriate width and left-position, so this is in a different for-loop:
for(var i=0; i<arr.length; i++){
arr[i].totalColumns=0;
if(arr[i].cols.length>1){ //if event collides
var conflictGroup=[]; //store here each column in the current event group
var conflictingColumns=[]; //and here the column of each of the events in the group
addConflictsToGroup(arr[i]);
function addConflictsToGroup(a){
for(k=0;k<a.cols.length;k++){
if(conflictGroup.indexOf(a.cols[k])===-1){ //don't add same event twice to avoid infinite loop
conflictGroup.push(a.cols[k]);
conflictingColumns.push(arr[a.cols[k]].column);
addConflictsToGroup(arr[a.cols[k]]); //check also the events this event conflicts with
}
}
}
arr[i].totalColumns=Math.max.apply(null, conflictingColumns); //set the greatest value as number of columns
}
arr[i].width=(600/(arr[i].totalColumns+1))+'px';
arr[i].left=(600/(arr[i].totalColumns+1)*arr[i].column)+'px';
}
return arr;
}