forked from chrisnunes57/Draggin.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
draggin.js
168 lines (149 loc) · 6.52 KB
/
draggin.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
156
157
158
159
160
161
162
163
164
165
166
167
168
document.body.onload = function(){
//Apply some basic styles
var css = ".draggable{cursor: move;display: inline-block;} .text{display: inline-block; cursor: move;} .text:focus{cursor: auto;} .text-wrapper{width: 100%;position: relative;} .wrap{position: absolute;margin: auto;top: 0;bottom: 0;left: 0;right: 0;}';";
var style = document.createElement('style');
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
document.getElementsByTagName('head')[0].appendChild(style);
// Select all elements with the 'draggable' class and stores them in the 'elements' variable
var elements = document.querySelectorAll(".draggable");
// Creates an additional array of all text elements
var texts = document.querySelectorAll(".text");
// Variable to store z index of last moved element
z = 1;
// Variable to store if you are currently editing text
editing = false;
// Stores the last edited text element
var editedText;
// Stores the last edited element
var tgt;
var clickTimer = null;
// Adds the mousedown listener on the body element, to listen for when you click away from an element
document.body.addEventListener('mousedown', cancel);
document.body.addEventListener('touchstart', cancel);
// Stops editing text when you click away from it
function cancel(evt){
// If the element clicked on is not text
if(!event.target.classList.contains("text")){
editing = false;
// Else, exit out of the edited text
if(editing){
editedText.blur();
}
}
}
// Adds event listeners to every element that has the draggable class
for(var i = 0; i < elements.length; i++){
elements[i].addEventListener('mousedown', drag);
elements[i].addEventListener('touchstart', handleTouch);
b = elements[i].getBoundingClientRect();
// Calculate the initial offset of the element from the top left of the page and stores it as a property of the element
elements[i].initialOffsetX = b.left + window.scrollX;
elements[i].initialOffsetY = b.top + window.scrollY;
elements[i].x = b.left;
elements[i].y = b.top;
elements[i].style.cursor = "move";
document.addEventListener('mouseup', end);
document.addEventListener('touchend', end);
};
// Adds a mouse event for a doubleclick on the text element and wraps text element in divs
for(let i = 0; i < texts.length; i++){
texts[i].addEventListener("dblclick", editText);
var div = document.createElement("div");
div.className = "text-wrapper";
var parent = texts[i].parentNode;
parent.insertBefore(div,texts[i]);
div.appendChild(texts[i]);
div.style.height = outerHeight(texts[i])+"px";
var div = document.createElement("div");
div.className = "wrap";
var parent = texts[i].parentNode;
parent.insertBefore(div,texts[i]);
div.appendChild(texts[i]);
// Lets you edit text
texts[i].contentEditable = "true";
}
// Focuses on the text element
function editText(evt){
editedText = evt.target;
editing = true;
editedText.focus();
}
function handleTouch(evt){
evt.preventDefault();
drag(evt);
if (clickTimer == null) {
clickTimer = setTimeout(function () {
clickTimer = null;
}, 500)
} else {
clearTimeout(clickTimer);
clickTimer = null;
editText(evt);
}
}
// Main logic, called when the mouse is clicked
function drag(event) {
// If the targeted element is not text
if(!event.target.classList.contains("text")){
// Set editing to false and lose focus on the text field
editing = false;
if(editing){
editedText.blur();
}
}
// If you are not clicking on a text element that is currently being edited
if(!editing){
// Prevent default behavior and increase z index to bring the new element to the front
event.preventDefault();
moving = true;
z = z+1;
// Identify which element was clicked and store in the 'tgt' element, then get position properties of it
tgt = event.target;
tgt.attributeName = 'test';
b = tgt.getBoundingClientRect();
var x = b.left + window.scrollX;
var y = b.top + window.scrollY;
offsetX = event.pageX || event.changedTouches[0].pageX;
offsetY = event.pageY || event.changedTouches[0].pageY;
document.addEventListener('mousemove',function(e) {
// If the page has been clicked and an element is being dragged
if(moving === true){
// Calculate the new position of the element, relative to the top left of the page
var dx = e.pageX - offsetX + x - tgt.initialOffsetX;
var dy = e.pageY - offsetY + y - tgt.initialOffsetY;
// Apply the styles to the element
var position = 'transform: translate('+dx+'px, '+dy+'px);z-index:'+z+';';
tgt.setAttribute('style', position);
};
});
document.addEventListener('touchmove',function(e) {
var touches = e.changedTouches;
// If the page has been clicked and an element is being dragged
if(moving === true){
for(let i = 0; i < touches.length; i++){
// Calculate the new position of the element, relative to the top left of the page
var dx = touches[i].pageX - offsetX + x - tgt.initialOffsetX;
var dy = touches[i].pageY - offsetY + y - tgt.initialOffsetY;
// Apply the styles to the element
var position = 'transform: translate('+dx+'px, '+dy+'px);z-index:'+z+';';
tgt.setAttribute('style', position);
}
};
});
}
};
function end(evt) {
// When the mouse is lifted up, set moving to false
moving = false;
};
function outerHeight(el) {
var height = el.offsetHeight;
var style = getComputedStyle(el);
height += parseInt(style.marginTop) + parseInt(style.marginBottom);
return height;
}
}