Mover elementos entre dos contenedores con Native JS arrastrar y soltar

Tiempo de ejecución: 30 minutos. Empezar

Autor: lukasolson
Views Total: 5,083
Sitio oficial: Ir a la web
Actualizado: October 31, 2016
Licencia: MIT

Vista prévia

Mover elementos entre dos contenedores con Native JS arrastrar y soltar

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

Te puede interesar: