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