|
CS479/579 - Web Programming II
|
Displaying ./code/ES/move.html
<!-- A comment -->
<!DOCTYPE html>
<html onmouseup='drop();' onmousemove='move(event);'>
<head>
<title> </title>
<meta charset='utf-8'>
<!--
<link rel='stylesheet' src='styles.css' type='text/css' />
-->
<style>
table { margin-left: 1in; margin-top: .5in; }
#container {
width: 200px; height: 300px; border: 1px solid red;
}
.item { width: 198px; height: 50px; border: 1px solid black;
background-color: white;
}
.spacer { width: 200px; height: 52px; }
</style>
<script>
var obj = null;
var spacer = null;
var spacerpos = 0;
function offsets(e) {
var xo = 0, yo = 0;
do {
xo += e.offsetLeft;
yo += e.offsetTop;
} while (e = e.offsetParent);
return {xo : xo, yo : yo};
}
/**
* When an element in the class 'item' is clicked on, we remove it from the
* parent and add it to the document body (so it can be moved outside of the
* parent element,) as an absolutely positioned element. We create a "spacer"
* element to replace it and remember where we put the spacer.
*/
function grab(ev) {
if (ev.target == undefined) return;
if (ev.target.className != "item") return;
// Prevents the copy-paste drag event on the element we're dragging:
ev.preventDefault();
// Create the spacer:
spacer = document.createElement("div");
spacer.className = "spacer";
spacer.innerHTML = " This space intentionally left blank";
// Compute offsets for the target element:
var off = offsets(ev.target);
obj = { e: ev.target, xo: ev.clientX - off.xo, yo: ev.clientY - off.yo };
// c == the parent element:
var c = obj.e.parentNode;
// Insert the spacer, then remove the dragged element:
c.insertBefore(spacer, obj.e);
c.removeChild(obj.e);
// Compute the spacers index location in the parent's child node-list:
for(spacerpos = 0; spacerpos < c.childNodes.length && c.childNodes[spacerpos] != spacer; spacerpos++);
// Add the removed element to the document.body. It must be in the DOM
// somewhere in order to be displayed.
document.body.appendChild(obj.e);
obj.e.style.position = "absolute";
obj.e.style.top = (ev.clientY-obj.yo) + "px";
obj.e.style.left = (ev.clientX-obj.xo) + "px";
}
function drop() {
if (obj == null) return;
// Set back to normal static positioning:
obj.e.style.position = "static";
obj.e.style.top = "initial";
obj.e.style.left = "initial";
var c = document.getElementById("container");
// Insert before the spacer, then remove the spacer:
c.insertBefore(obj.e,spacer);
spacer.parentNode.removeChild(spacer);
spacer = null;
obj = null;
}
/**
* We cannot use a mousemove on the container itself as it is blocked by the
* element we're moving, so we have to do the work in a global move handler.
*/
function move(ev) {
if (obj == null) return;
obj.e.style.top = (ev.clientY-obj.yo) + "px";
obj.e.style.left = (ev.clientX-obj.xo) + "px";
// Check if the y mouse coordinate is inside the container:
var c = document.getElementById("container");
var off = offsets(c);
var y = ev.clientY - off.yo;
// Should probably use the clientHeight for the container rather than 300:
if (y < 0 || y > 300) return;
// Find the child node index the mouse is "over":
for(var yp = 50, i = 0; i < c.childNodes.length && yp < y; i++, yp+=50);
// If we've gone past the number of nodes:
if (i == c.childNodes.length) {
if (c.lastChild != spacer) {
spacerpos = i-1;
c.appendChild(spacer);
}
return;
}
y -= (yp-50);
// Just put the spacer under the cursor as much as possible:
if (c.childNodes[i] == spacer) return;
else {
console.log(y, yp, i);
if (i < c.childNodes.length-1) {
// We use spacerpos to determine if the spacer is above or below this
// node and adjust the insertion accordingly.
if (spacerpos > i) c.insertBefore(spacer,c.childNodes[i]);
else c.insertBefore(spacer,c.childNodes[i+1]);
} else c.appendChild(spacer);
spacerpos = i;
}
}
function additem() {
var item = document.createElement("div");
item.className = "item";
item.innerHTML = document.getElementById("name").value;
document.getElementById("container").appendChild(item);
}
</script>
</head>
<body>
<table>
<tr><td>
<!-- Make sure there are no text nodes (i.e. any whitespace, etc,) in the 'container' -->
<div id='container' onmousedown='grab(event);' ><div class='item'> Item 1</div><div class='item'> Item 10</div><div class='item'> Item 5</div></div>
<tr><td>
<!-- Input and button to add more item elements to the container: -->
<input type='text' id='name'><br>
<button onclick='additem();'> Add something </button>
</table>
</body>
</html>
|