-
Notifications
You must be signed in to change notification settings - Fork 3
/
meteor-drag-event.js
155 lines (135 loc) · 4.33 KB
/
meteor-drag-event.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/**
* Meteor Drag Event
* @author Yonatan Wolowelsky http://grmmph.com
* @licence MIT
* @docs https://github.com/grmmph/meteor-drag-event
*
* @description Addding drag event to Meteor by Extending Blaze event handlers
*/
(function () {
if (!Meteor.isClient) {
return;
}
var MeteorDragEvent = class MeteorDragEvent {
constructor(rootElem, selector, oldHandler) {
this.oldHandler = oldHandler; // old event handler from Blaze
this.selector = selector; // selector defined by the user (e.g. `#my-elem`)
this.dragEvent = new CustomEvent('drag');
this.rootElem = rootElem;
this.selected; // selected element that is been dragged
this.element; // (J)Queried current selected element
this.posX = 0; // current absolute position X
this.posY = 0; // current absolute position Y
this.dx = 0; // Difference between old posX and new posX. (relative position from last known position)
this.dy = 0; // Difference between old posY and new posY. (relative position from last known position)
this.type; // "dragstart" || "dragging" || "dragend"
this.isFirstDragging = true;
// Init
this.setEvents();
};
/**
* @desc Handle draging on mouse move
* @param element {DOM Object} Selected drag element
* @param evt {Object} Mousedown Event
*/
dragstart(elem, evt) {
this.dragType = 'dragstart';
this.handler(evt);
this.selected = elem;
}
/**
* @desc Handle draging on mouse move
* @param evt {Object} Mousemove Event
*/
dragging(evt) {
if (!this.selected) {
return;
}
newXPos = document.all ? window.event.clientX : evt.pageX;
newYPos = document.all ? window.event.clientY : evt.pageY;
if (this.isFirstDragging) {
this.dx = 0;
this.dy = 0;
this.isFirstDragging = false;
} else {
this.dx = newXPos - this.posX;
this.dy = newYPos - this.posY;
}
this.posX = newXPos;
this.posY = newYPos;
this.dragType = 'dragging';
this.element.trigger('drag', evt);
}
/**
* @desc Handle drag end on mouse up
* @param evt {Object} Mouseup Event
*/
dragend(evt) {
if (!this.selected) {
return;
}
this.dragType = 'dragend';
this.selected = null;
this.dx = 0;
this.dy = 0;
this.isFirstDragging = true;
this.element.trigger('drag', evt);
}
/**
* @desc new event handler to pass into Blaze events
* @param evt {Object} event to pass
* @param element {DOM Object} draggable dom element
* @returns extened event handler function
*/
handler(evt, element) {
evt.drag = {};
evt.drag.dx = this.dx;
evt.drag.dy = this.dy;
evt.drag.type = this.dragType;
return this.oldHandler.apply(this, [evt]);
}
/**
* @desc Sort of an init function to setup all the mouse events
*/
setEvents() {
var self = this;
$(this.rootElem).on('drag', this.selector, function (initialEvent, currentEvent) {
if (currentEvent) {
initialEvent.currentEvent = currentEvent;
initialEvent.targetMouseOn = currentEvent.target;
}
self.handler(initialEvent, this);
});
$(this.rootElem).on('mousedown', this.selector, function (evt) {
self.element = $(this);
evt.targetMouseOn = evt.target;
self.dragstart(this, evt);
return false;
});
$(document).on('mousemove', function (evt) {
self.dragging(evt);
});
$(document).on('mouseup', function (evt) {
self.dragend(evt);
});
}
};
try {
// Extend Blaze to support the drag event
Blaze._EventSupport.eventsToDelegate.drag = 1;
var oldDelegateEvents = Blaze._DOMBackend.Events.delegateEvents;
Blaze._DOMBackend.Events.delegateEvents = function (elem, type, selector, handler) {
if (type === 'drag') {
$(document).ready(function () {
new MeteorDragEvent(elem, selector, handler);
});
} else {
oldDelegateEvents.apply(this, arguments);
}
}
}
catch (err) {
// NOTE: For the first time meteor will try to initilize this, it will catch the error.
// This is something related to Meteor magic that handles it again when Blaze is ready for extentions.
}
})();