我正在尝试增强我在stackoverlow(HTML markup for multi-day calendar events)找到的jquery片段,但我遇到了一个特殊的问题,我真的不知道如何克服。基本上我想要实现的是避免在日历中将多日事件堆叠在一起。由于我只有1个声望点(就像我的新手一样),我不能用屏幕转储解释自己,但必须(至少尝试)以书面形式解释自己。
所以,这是我的问题。下面的数组events []中的索引[3]从第四天开始,但由于第四天也包含索引[0,1],eventCount设置为3.这意味着如果在第四天发生新事件,它将被给出evenCount 4.到目前为止没问题。然而在第五天有三个事件(索引[0,3,4])。现在......这是我的问题。索引[3]在eventCount 3的第4天开始并持续到第12天,而index [5]从第5天开始,并且因为当天只有3个事件而被赋予与index [3]相同的eventCount。这是代码片段(基本代码的荣誉为ThinkingStiff):
var events = [{ from: 3, to: 9 }, { from: 4, to: 4 }, { from: 9, to: 11 },{ from: 4, to: 12 },{ from: 5, to: 7 }];
for( var eventIndex = 0, event; event = events[eventIndex], eventIndex < events.length; eventIndex++ ) {
for( var dayIndex = event.from; dayIndex <= event.to; dayIndex++ ) {
var dayElement = document.getElementById( 'day' + dayIndex ),
firstDay = document.getElementsByClassName( 'event' + eventIndex ),
top;
if( firstDay.length ) {
top = firstDay[0].style.top;
} else {
var eventCount = dayElement.getElementsByClassName( 'event' ).length;
top = ( eventCount * 20 ) + 'px';
};
var html = '<div '
+ 'class="event event' + eventIndex + '" '
+ 'style="top: ' + top + ';">'
+ eventIndex
+ '</div>';
dayElement.insertAdjacentHTML( 'beforeEnd', html );
};
};
我想要实现的是一个检查,确定是否需要在添加新的eventCounts之前将前一天的事件添加到eventCount,以便新事件不会叠加在现有事件之上。我如何实现这一目标?
虽然我在这 - 但事实证明,数组不允许其他参数,例如“subject”。是否可以扩展数组以包含自定义参数而不会破坏整个代码?
非常感谢每一个提示。
答案 0 :(得分:0)
我也在Facebook上抛出这个问题,以便将它扩展到更广泛的程序员群体,我得到了这个梦幻般的解决方案,我改进了一点以满足我的特定需求。 (我遗漏了CSS和HTML - 您可以在下面的链接中找到它)
Multi-day event calendar with javascript
var events = [{
name: 'Pelle',
color: 'red',
from: 3,
to: 9
}, {
name: 'Pelle',
color: '#c93',
from: 9,
to: 10
}, {
name: 'Martin',
color: 'blue',
from: 4,
to: 4
}, {
name: 'Willy',
color: 'green',
from: 9,
to: 11
}, {
name: 'Erik',
color: 'magenta',
from: 4,
to: 12
}, {
name: 'Barbro',
color: 'yellow',
from: 5,
to: 7
}, {
name: 'Ludwig',
color: '#39c',
from: 11,
to: 14
}];
var daysInMonth = 31,
firstDayOfMonth = 1, // 0 = Monday and so on
slotsInDay = 4, // How many slots can be in a single day? Depends on height.
eventHeightPx = 20,
days = {},
dayNames = ['Måndag', 'Tisdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lördag', 'Söndag'],
s,
i,
d;
// Populate our days-object.
// Each day is named after the date and contains events and slots
for (i = 0; i < daysInMonth; i++) {
days[i + 1] = {
events: [],
slots: []
};
}
// Run through all the events and push a copy of it to all days where it occurs.
// Also assign them unique IDs.
for (var eventIndex = 0; eventIndex < events.length; eventIndex++) {
events[eventIndex].id = eventIndex;
for (var dayIndex = events[eventIndex].from; dayIndex <= events[eventIndex].to; dayIndex++) {
days[dayIndex].events.push(events[eventIndex]);
}
}
// Output the HTML for the days of the calendar
// Each day is a list item in the calendar list
// Day names
for (i = 0; i < dayNames.length; i++) {
$('#calendar').append('<li class="dayName">' + dayNames[i] + '</li>');
}
// Last month
for (i = 0; i < firstDayOfMonth; i++) {
$('#calendar').append('<li class="dayInPreviousMonth"></li>');
}
// This month
for (var day in days) {
$('#calendar').append('<li data-date="' + day + '" class="dayInThisMonth">' + day + '</li>');
}
// Next month (to fill out the full last week)
for (var i = 0; i < 7 - (firstDayOfMonth + daysInMonth) % 7; i++) {
$('#calendar').append('<li class="dayInNextMonth"></li>');
}
// Run through all the days of this month
$('.dayInThisMonth').each(function () {
var date = $(this).data('date'); // Grab date from the data-attribute
// If this day have events
if (days[date].events.length) {
var s,
useSlot;
c('\n*** Day ' + date + ' ***\n');
// Run through all the events for this day
for (var e in days[date].events) {
c('\nEvent id ' + days[date].events[e].id +
' name ' + days[date].events[e].name +
' from ' + days[date].events[e].from +
' to ' + days[date].events[e].to);
useSlot = -1;
if(date != days[date].events[e].from) {
// If this is not the first day for the event
// check the slots in the first day of the event to find the position
c("Event should be previously allocated.");
for (s = 0; s < slotsInDay; s++) {
c('Checking slot ' + s + ' in day '+ days[date].events[e].from);
if (days[days[date].events[e].from].slots[s] !== undefined &&
days[days[date].events[e].from].slots[s] == days[date].events[e].id) {
c('Found this event. Use that slot.');
useSlot = s;
break;
}
}
}
else
{
// If this is the first day of the event
// find the first open slot of current day.
for (s = 0; s < slotsInDay; s++) {
c('Checking slot ' + s + ' for availabilty');
if (days[date].slots[s] !== undefined) {
c('Slot is not free. Allocated by ' + days[date].slots[s]);
slotIsFree = false;
} else {
c('Slot is free. Use it.');
useSlot = s;
break;
}
}
}
c("Will use slot " + s);
var top = s * eventHeightPx;
$(this).append('<div class="event ' + (days[date].events[e].from == date ? 'firstEvent' : '') +
' ' + (days[date].events[e].to == date ? 'lastEvent' : '') +
'" style="background-color: ' + days[date].events[e].color + ';top: ' + top + 'px">' + days[date].events[e].name + '</div>');
c('Allocating slot '+s+' to event id '+days[date].events[e].id);
days[date].slots[s] = days[date].events[e].id;
}
}
});
function c(t) {
$('#console').append(t + "\n");
}
这个整洁的小javascript就像我希望的那样呈现它。通过一些调整,我删除了HTML渲染,因为日历网格是用VB.NET渲染的。我要感谢Niclas Lardh他的快速编程。