event binding optimization, fixed optimization-related mouseover bug
This commit is contained in:
parent
0e3e04bbdf
commit
16edfe71e7
3 changed files with 91 additions and 75 deletions
|
@ -347,7 +347,7 @@ function Agenda(element, options, methods) {
|
|||
/* Event Rendering
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
function renderEvents(events) {
|
||||
function renderEvents(events, modifiedEventId) {
|
||||
view.reportEvents(cachedEvents = events);
|
||||
var i, len=events.length,
|
||||
dayEvents=[],
|
||||
|
@ -359,14 +359,14 @@ function Agenda(element, options, methods) {
|
|||
slotEvents.push(events[i]);
|
||||
}
|
||||
}
|
||||
renderDaySegs(compileDaySegs(dayEvents));
|
||||
renderSlotSegs(compileSlotSegs(slotEvents));
|
||||
renderDaySegs(compileDaySegs(dayEvents), modifiedEventId);
|
||||
renderSlotSegs(compileSlotSegs(slotEvents), modifiedEventId);
|
||||
}
|
||||
|
||||
|
||||
function rerenderEvents() {
|
||||
function rerenderEvents(modifiedEventId) {
|
||||
clearEvents();
|
||||
renderEvents(cachedEvents);
|
||||
renderEvents(cachedEvents, modifiedEventId);
|
||||
}
|
||||
|
||||
|
||||
|
@ -427,7 +427,7 @@ function Agenda(element, options, methods) {
|
|||
|
||||
// renders 'all-day' events at the top
|
||||
|
||||
function renderDaySegs(segs) {
|
||||
function renderDaySegs(segs, modifiedEventId) {
|
||||
if (options.allDaySlot) {
|
||||
_renderDaySegs(
|
||||
segs,
|
||||
|
@ -445,7 +445,8 @@ function Agenda(element, options, methods) {
|
|||
return axisWidth + colContentPositions.right(day2col(dayOfWeek));
|
||||
},
|
||||
daySegmentContainer,
|
||||
bootstrapDayEventHandlers
|
||||
bindDaySegHandlers,
|
||||
modifiedEventId
|
||||
);
|
||||
updateSize(viewWidth, viewHeight); // might have pushed the body down, so resize
|
||||
}
|
||||
|
@ -455,7 +456,7 @@ function Agenda(element, options, methods) {
|
|||
|
||||
// renders events in the 'time slots' at the bottom
|
||||
|
||||
function renderSlotSegs(segs) {
|
||||
function renderSlotSegs(segs, modifiedEventId) {
|
||||
|
||||
var i, segCnt=segs.length, seg,
|
||||
event,
|
||||
|
@ -467,7 +468,7 @@ function Agenda(element, options, methods) {
|
|||
outerWidth,
|
||||
left,
|
||||
html='',
|
||||
_eventElements,
|
||||
eventElements,
|
||||
eventElement,
|
||||
triggerRes,
|
||||
vsideCache={},
|
||||
|
@ -527,13 +528,13 @@ function Agenda(element, options, methods) {
|
|||
"</div>";
|
||||
}
|
||||
slotSegmentContainer[0].innerHTML = html;
|
||||
_eventElements = $.makeArray(slotSegmentContainer[0].childNodes); // TODO: look at .children() again
|
||||
eventElements = slotSegmentContainer.children();
|
||||
|
||||
// retrieve elements, run through eventRender callback, bind event handlers
|
||||
for (i=0; i<segCnt; i++) {
|
||||
seg = segs[i];
|
||||
event = seg.event;
|
||||
eventElement = $(_eventElements[i]);
|
||||
eventElement = $(eventElements[i]); // faster than eq()
|
||||
triggerRes = view.trigger('eventRender', event, event, eventElement);
|
||||
if (triggerRes === false) {
|
||||
eventElement.remove();
|
||||
|
@ -549,11 +550,17 @@ function Agenda(element, options, methods) {
|
|||
.appendTo(slotSegmentContainer);
|
||||
}
|
||||
seg.element = eventElement;
|
||||
bootstrapSlotEventHandlers(event, seg, eventElement);
|
||||
if (event._id === modifiedEventId) {
|
||||
bindSlotSegHandlers(event, eventElement, seg);
|
||||
}else{
|
||||
eventElement[0]._fci = i; // for lazySegBind
|
||||
}
|
||||
view.reportEventElement(event, eventElement);
|
||||
}
|
||||
}
|
||||
|
||||
lazySegBind(slotSegmentContainer, segs, bindSlotSegHandlers);
|
||||
|
||||
// record event sides and title positions
|
||||
for (i=0; i<segCnt; i++) {
|
||||
seg = segs[i];
|
||||
|
@ -611,41 +618,27 @@ function Agenda(element, options, methods) {
|
|||
|
||||
|
||||
|
||||
function bootstrapDayEventHandlers(event, seg, eventElement) {
|
||||
function mouseover(ev) {
|
||||
view.trigger('eventMouseover', this, event, ev);
|
||||
eventElement.unbind('mouseover', mouseover);
|
||||
setTimeout(function() { // because IE will immediately trigger eventElementHandlers's mouseover
|
||||
view.eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable == undefined && options.editable) {
|
||||
draggableDayEvent(event, eventElement, seg.isStart);
|
||||
if (seg.isEnd) {
|
||||
view.resizableDayEvent(event, eventElement, colWidth);
|
||||
}
|
||||
}
|
||||
},0);
|
||||
function bindDaySegHandlers(event, eventElement, seg) {
|
||||
view.eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable == undefined && options.editable) {
|
||||
draggableDayEvent(event, eventElement, seg.isStart);
|
||||
if (seg.isEnd) {
|
||||
view.resizableDayEvent(event, eventElement, colWidth);
|
||||
}
|
||||
}
|
||||
eventElement.mouseover(mouseover);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function bootstrapSlotEventHandlers(event, seg, eventElement) {
|
||||
function mouseover(ev) {
|
||||
view.trigger('eventMouseover', this, event, ev);
|
||||
eventElement.unbind('mouseover', mouseover);
|
||||
setTimeout(function() { // because IE will immediately trigger eventElementHandlers's mouseover
|
||||
view.eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable == undefined && options.editable) {
|
||||
var timeElement = eventElement.find('span.fc-event-time');
|
||||
draggableSlotEvent(event, eventElement, timeElement);
|
||||
if (seg.isEnd) {
|
||||
resizableSlotEvent(event, eventElement, timeElement);
|
||||
}
|
||||
}
|
||||
},0);
|
||||
function bindSlotSegHandlers(event, eventElement, seg) {
|
||||
view.eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable == undefined && options.editable) {
|
||||
var timeElement = eventElement.find('span.fc-event-time');
|
||||
draggableSlotEvent(event, eventElement, timeElement);
|
||||
if (seg.isEnd) {
|
||||
resizableSlotEvent(event, eventElement, timeElement);
|
||||
}
|
||||
}
|
||||
eventElement.mouseover(mouseover);
|
||||
}
|
||||
|
||||
|
||||
|
|
70
src/grid.js
70
src/grid.js
|
@ -370,9 +370,9 @@ function Grid(element, options, methods) {
|
|||
}
|
||||
|
||||
|
||||
function rerenderEvents() {
|
||||
function rerenderEvents(modifiedEventId) {
|
||||
clearEvents();
|
||||
renderSegs(compileSegs(cachedEvents));
|
||||
renderSegs(compileSegs(cachedEvents), modifiedEventId);
|
||||
}
|
||||
|
||||
|
||||
|
@ -409,7 +409,7 @@ function Grid(element, options, methods) {
|
|||
|
||||
|
||||
|
||||
function renderSegs(segs) {
|
||||
function renderSegs(segs, modifiedEventId) {
|
||||
_renderDaySegs(
|
||||
segs,
|
||||
rowCnt,
|
||||
|
@ -420,7 +420,8 @@ function Grid(element, options, methods) {
|
|||
dayContentPositions.left,
|
||||
dayContentPositions.right,
|
||||
segmentContainer,
|
||||
mouseoverBind
|
||||
bindSegHandlers,
|
||||
modifiedEventId
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -437,22 +438,14 @@ function Grid(element, options, methods) {
|
|||
|
||||
|
||||
|
||||
|
||||
function mouseoverBind(event, seg, eventElement) {
|
||||
function mouseover(ev) {
|
||||
eventElement.unbind('mouseover', mouseover);
|
||||
view.trigger('eventMouseover', this, event, ev);
|
||||
setTimeout(function() { // because IE will immediately trigger the new mouseover handlers
|
||||
view.eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable == undefined && options.editable) {
|
||||
draggableEvent(event, eventElement);
|
||||
if (seg.isEnd) {
|
||||
view.resizableDayEvent(event, eventElement, colWidth);
|
||||
}
|
||||
}
|
||||
},0);
|
||||
function bindSegHandlers(event, eventElement, seg) {
|
||||
view.eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable == undefined && options.editable) {
|
||||
draggableEvent(event, eventElement);
|
||||
if (seg.isEnd) {
|
||||
view.resizableDayEvent(event, eventElement, colWidth);
|
||||
}
|
||||
}
|
||||
eventElement.mouseover(mouseover);
|
||||
}
|
||||
|
||||
|
||||
|
@ -519,7 +512,7 @@ function Grid(element, options, methods) {
|
|||
};
|
||||
|
||||
|
||||
function _renderDaySegs(segs, rowCnt, view, minLeft, maxLeft, getRow, dayContentLeft, dayContentRight, segmentContainer, mouseoverBind) {
|
||||
function _renderDaySegs(segs, rowCnt, view, minLeft, maxLeft, getRow, dayContentLeft, dayContentRight, segmentContainer, bindSegHandlers, modifiedEventId) {
|
||||
|
||||
var options=view.options,
|
||||
rtl=options.isRTL,
|
||||
|
@ -528,7 +521,7 @@ function _renderDaySegs(segs, rowCnt, view, minLeft, maxLeft, getRow, dayContent
|
|||
className,
|
||||
left, right,
|
||||
html='',
|
||||
_eventElements,
|
||||
eventElements,
|
||||
eventElement,
|
||||
triggerRes,
|
||||
hsideCache={},
|
||||
|
@ -572,17 +565,20 @@ function _renderDaySegs(segs, rowCnt, view, minLeft, maxLeft, getRow, dayContent
|
|||
:'') +
|
||||
"<span class='fc-event-title'>" + htmlEscape(event.title) + "</span>" +
|
||||
"</a>" +
|
||||
((event.editable || event.editable == undefined && options.editable) && !options.disableResizing && $.fn.resizable ?
|
||||
"<div class='ui-resizable-handle ui-resizable-" + (rtl ? 'w' : 'e') + "'></div>"
|
||||
: '') +
|
||||
"</div>";
|
||||
seg.left = left;
|
||||
seg.outerWidth = right - left;
|
||||
}
|
||||
segmentContainer[0].innerHTML = html;
|
||||
_eventElements = $.makeArray(segmentContainer[0].childNodes); // TODO: look at .children() again
|
||||
eventElements = segmentContainer.children();
|
||||
|
||||
// retrieve elements, run through eventRender callback, bind handlers
|
||||
for (i=0; i<segCnt; i++) {
|
||||
seg = segs[i];
|
||||
eventElement = $(_eventElements[i]);
|
||||
eventElement = $(eventElements[i]); // faster than eq()
|
||||
event = seg.event;
|
||||
triggerRes = view.trigger('eventRender', event, event, eventElement);
|
||||
if (triggerRes === false) {
|
||||
|
@ -598,11 +594,17 @@ function _renderDaySegs(segs, rowCnt, view, minLeft, maxLeft, getRow, dayContent
|
|||
.appendTo(segmentContainer);
|
||||
}
|
||||
seg.element = eventElement;
|
||||
mouseoverBind(event, seg, eventElement);
|
||||
if (event._id === modifiedEventId) {
|
||||
bindSegHandlers(event, eventElement, seg);
|
||||
}else{
|
||||
eventElement[0]._fci = i; // for lazySegBind
|
||||
}
|
||||
view.reportEventElement(event, eventElement);
|
||||
}
|
||||
}
|
||||
|
||||
lazySegBind(segmentContainer, segs, bindSegHandlers);
|
||||
|
||||
// record event horizontal sides
|
||||
for (i=0; i<segCnt; i++) {
|
||||
seg = segs[i];
|
||||
|
@ -671,3 +673,23 @@ function cssKey(_element) {
|
|||
}
|
||||
|
||||
|
||||
function lazySegBind(container, segs, bindHandlers) {
|
||||
container.unbind('mouseover').mouseover(function(ev) {
|
||||
var parent=ev.target, e,
|
||||
i, seg;
|
||||
while (parent != this) {
|
||||
e = parent;
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
if ((i = e._fci) != undefined) {
|
||||
e._fci = undefined;
|
||||
seg = segs[i];
|
||||
bindHandlers(seg.event, seg.element, seg);
|
||||
$(ev.target).trigger(ev);
|
||||
}
|
||||
ev.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
21
src/view.js
21
src/view.js
|
@ -117,27 +117,29 @@ var viewMethods = {
|
|||
|
||||
eventDrop: function(e, event, dayDelta, minuteDelta, allDay, ev, ui) {
|
||||
var view = this,
|
||||
oldAllDay = event.allDay;
|
||||
view.moveEvents(view.eventsByID[event._id], dayDelta, minuteDelta, allDay);
|
||||
oldAllDay = event.allDay,
|
||||
eventId = event._id;
|
||||
view.moveEvents(view.eventsByID[eventId], dayDelta, minuteDelta, allDay);
|
||||
view.trigger('eventDrop', e, event, dayDelta, minuteDelta, allDay, function() { // TODO: change docs
|
||||
// TODO: investigate cases where this inverse technique might not work
|
||||
view.moveEvents(view.eventsByID[event._id], -dayDelta, -minuteDelta, oldAllDay);
|
||||
view.moveEvents(view.eventsByID[eventId], -dayDelta, -minuteDelta, oldAllDay);
|
||||
view.rerenderEvents();
|
||||
}, ev, ui);
|
||||
view.eventsChanged = true;
|
||||
view.rerenderEvents();
|
||||
view.rerenderEvents(eventId);
|
||||
},
|
||||
|
||||
eventResize: function(e, event, dayDelta, minuteDelta, ev, ui) {
|
||||
var view = this;
|
||||
view.elongateEvents(view.eventsByID[event._id], dayDelta, minuteDelta);
|
||||
var view = this,
|
||||
eventId = event._id;
|
||||
view.elongateEvents(view.eventsByID[eventId], dayDelta, minuteDelta);
|
||||
view.trigger('eventResize', e, event, dayDelta, minuteDelta, function() {
|
||||
// TODO: investigate cases where this inverse technique might not work
|
||||
view.elongateEvents(view.eventsByID[event._id], -dayDelta, -minuteDelta);
|
||||
view.elongateEvents(view.eventsByID[eventId], -dayDelta, -minuteDelta);
|
||||
view.rerenderEvents();
|
||||
}, ev, ui);
|
||||
view.eventsChanged = true;
|
||||
view.rerenderEvents();
|
||||
view.rerenderEvents(eventId);
|
||||
},
|
||||
|
||||
|
||||
|
@ -202,7 +204,7 @@ var viewMethods = {
|
|||
var view = this;
|
||||
if (!view.options.disableResizing && eventElement.resizable) {
|
||||
eventElement.resizable({
|
||||
handles: view.options.isRTL ? 'w' : 'e',
|
||||
handles: view.options.isRTL ? {w:'div.ui-resizable-w'} : {e:'div.ui-resizable-e'},
|
||||
grid: colWidth,
|
||||
minWidth: colWidth/2, // need this or else IE throws errors when too small
|
||||
containment: view.element.parent().parent(), // the main element...
|
||||
|
@ -309,7 +311,6 @@ var viewMethods = {
|
|||
|
||||
|
||||
|
||||
|
||||
// event rendering calculation utilities
|
||||
|
||||
function stackSegs(segs) {
|
||||
|
|
Loading…
Reference in a new issue