Mover elementos entre dos contenedores con Native JS arrastrar y soltar
| Autor: | lukasolson |
|---|---|
| Views Total: | 5,083 |
| Sitio oficial: | Ir a la web |
| Actualizado: | October 31, 2016 |
| Licencia: | MIT |
Vista prévia
Descripción
Una solución de JavaScript pura muy simple para mover elementos entre contenedores/cajas por drag'n ' Drop.
Funcionamiento
Cree un contenedor para los elementos arrastrables.
<div id="available_metrics_filter"> <ul id="available_metrics_list"> </ul> </div>
Cree un contenedor para el área soltable.
<div id="selected_metrics"> <ul id="selected_metrics_list"> <li id="next_metric">Next Draggable</li> </ul> </div>
El código JavaScript para agregar elementos al contenedor arrastrable y habilitar la funcionalidad de arrastrar y soltar.
var droppables = new Array();
var itemBeingDragged = null;
var mouseDownPoint = {x: 0, y: 0};
function onDocumentMouseMove(mouseMoveEvent) {
var point = {x: mouseMoveEvent.pageX, y: mouseMoveEvent.pageY};
// Drag the draggable to this position
itemBeingDragged.dragTo(point);
// If there are any droppable elements at this position, notify them
for (var i = 0; i < droppables.length; i++) {
if (droppables[i].contains(point) && !droppables[i].isBeingDraggedOver) {
droppables[i].onDragEnter();
} else if (!droppables[i].contains(point) && droppables[i].isBeingDraggedOver) {
droppables[i].onDragExit();
}
}
}
function onDocumentMouseUp(mouseUpEvent) {
// If any droppable is being dragged over, accept the drop
for (var i = 0; i < droppables.length; i++) {
if (droppables[i].isBeingDraggedOver) {
droppables[i].onDragDrop(itemBeingDragged);
}
}
// Reset the position of the item being dragged and clear out the document event handlers
itemBeingDragged.reset(mouseUpEvent);
}
var Draggable = function(elementId) {
this.init(elementId);
};
Draggable.prototype = {
init: function(element) {
if (typeof element === "string") element = document.getElementById(element);
this.element = element;
this.element.className += "draggable";
var self = this;
this.element.onmousedown = function(mouseDownEvent) {
this.style.zIndex = "1000";
itemBeingDragged = self;
mouseDownPoint.x = mouseDownEvent.pageX;
mouseDownPoint.y = mouseDownEvent.pageY;
document.onmousemove = onDocumentMouseMove;
document.onmouseup = onDocumentMouseUp;
};
},
// Called when the mouse is moved (after having been pressed on this element)
dragTo: function(point) {
this.element.style.left = (point.x - mouseDownPoint.x) + "px";
this.element.style.top = (point.y - mouseDownPoint.y) + "px";
},
// Called when the mouse is lifted (after having been pressed on this element)
reset: function() {
this.element.style.zIndex = "";
this.element.style.left = "";
this.element.style.top = "";
itemBeingDragged = null;
mouseDownPoint.x = 0;
mouseDownPoint.y = 0;
document.onmousemove = null;
document.onmouseup = null;
}
};
// customDragDrop is a custom function which will be called when a Draggable is dropped
// on this Droppable; it is passed the Draggable that was dropped
var Droppable = function(element, customDragDrop) {
this.init(element, customDragDrop);
};
Droppable.prototype = {
init: function(element, customDragDrop) {
if (typeof element === "string") element = document.getElementById(element);
this.element = element;
this.isBeingDraggedOver = false;
this.customDragDrop = customDragDrop;
droppables.push(this);
},
// Calculate the top-left coordinate of this element
position: function() {
var position = {x: this.element.offsetLeft, y: this.element.offsetTop};
var offsetParent = this.element.offsetParent;
while (offsetParent) {
position.x += offsetParent.offsetLeft;
position.y += offsetParent.offsetTop;
offsetParent = offsetParent.offsetParent;
}
return position;
},
// Calculate whether the given coordinate falls within this element's boundaries
contains: function(point) {
var topLeft = this.position();
var bottomRight = {
x: topLeft.x + this.element.offsetWidth,
y: topLeft.y + this.element.offsetHeight
};
return (
topLeft.x < point.x
&& topLeft.y < point.y
&& point.x < bottomRight.x
&& point.y < bottomRight.y
);
},
// Called when an item is dragged into this element
onDragEnter: function() {
this.isBeingDraggedOver = true;
this.element.className += "dragOver";
},
// Called when an item is dragged out of this element
onDragExit: function() {
this.isBeingDraggedOver = false;
this.element.className = this.element.className.replace(/\bdragOver\b/, "");
},
// Called when an item is dropped on this element
onDragDrop: function(draggable) {
this.onDragExit();
this.customDragDrop(draggable);
}
};
window.onload = function() {
// custom data
var data = [
"These",
"Words",
"Can",
"Be",
"Dragged",
"And",
"Dropped",
"Over",
"On",
"The",
"Right",
"Side",
"Of",
"The",
"Screen"
];
var availableMetrics = document.getElementById("available_metrics_list");
for (var i = 0; i < data.length; i++) {
var liElement = document.createElement("li");
liElement.appendChild(document.createTextNode(data[i]));
availableMetrics.appendChild(liElement);
var liElementDraggable = new Draggable(liElement);
}
var availableMetricsDroppable = new Droppable(availableMetrics, function(draggable) {
if (this.element !== draggable.element.parentNode) {
this.element.appendChild(draggable.element);
}
});
var selectedMetricsDroppable = new Droppable("next_metric", function(draggable) {
if (this.element.parentNode !== draggable.element.parentNode) {
this.element.parentNode.insertBefore(draggable.element, this.element);
}
});
new Droppable("remove_metric", function(draggable) {
availableMetricsDroppable.onDragDrop(draggable);
});
}; El CSS de ejemplo para el estilo de los contenedores.
#available_metrics_filter {
margin: 5px;
border: 1px solid gray;
padding: 5px;
background-color: rgb(230, 230, 230);
}
#available_metrics_list {
padding: 0px;
border: 1px solid gray;
padding: 10px;
background-color: white;
}
#available_metrics_list li {
margin-top: -1px;
border: 1px solid gray;
padding: 5px;
list-style-type: none;
background-color: white;
}
#selected_metrics_list {
margin: 5px;
border: 1px solid gray;
padding: 10px;
background-color: white;
}
#selected_metrics_list li {
margin-top: -1px;
border: 1px solid gray;
padding: 5px;
list-style-type: none;
background-color: white;
}
#selected_metrics_list li:last-child { border: 1px dotted gray; }
#next_metric { color: gray; }
#remove_metric {
margin: 5px;
border: 1px dotted gray;
padding: 5px;
color: gray;
text-align: center;
background-color: white;
}
.draggable {
position: relative;
cursor: default;
}
.dragOver { background-color: rgb(232, 232, 255) !important; } Registro de cambios
10/31/2016
- Soporta MS Edge





