Aquí hay un ejemplo con la solución de coordenadas XY.
Working example on jsfiddle
El ejemplo se puede mejorar, pero es un buen punto de partida.
Simplemente realiza un seguimiento de la ubicación del mouse y comprueba si parece estar dentro de los cuadros delimitadores de los objetos que se pueden colocar. Por lo tanto, si el evento mouseup se activa en cualquiera de ellos, se descarta el objeto arrastrado.
También puede usar las coordenadas del objeto que está arrastrando para detectar si está en un cuadro desplegable, pero requiere un poco más de código para encontrar las coordenadas del cuadro delimitador y usar el mouse es suficiente para mí.
El código usa jQuery pero no jQueryUI. He probado en Chrome, Firefox y Opera, pero no en IE :)
También estoy agregando el código aquí si jsfiddle no está accesible.
HTML
<p>Drag orange boxes to grey ones</p>
<div class="droppable"></div>
<div class="droppable"></div>
<div class="droppable"></div>
<div class="droppable"></div>
<div class="draggable"></div>
<div class="draggable"></div>
<div class="draggable"></div>
CSS
.droppable {
width:50px;
height:50px;
float: left;
background-color: #DDD;
margin: 5px;
}
.draggable {
width:40px;
height:40px;
float: right;
background-color: #FC0;
margin: 5px;
cursor: pointer;
}
.dropped {
background-color: #FC0;
}
.somethingover {
background-color: #FCD;
}
JS
var dragged, mousex, mousey, coordinates = [];
var continueDragging = function(e) {
// Change the location of the draggable object
dragged.css({
"left": e.pageX - (dragged.width()/2),
"top": e.pageY - (dragged.height()/2)
});
// Check if we hit any boxes
for (var i in coordinates) {
if (mousex >= coordinates[i].left && mousex <= coordinates[i].right) {
if (mousey >= coordinates[i].top && mousey <= coordinates[i].bottom) {
// Yes, the mouse is on a droppable area
// Lets change the background color
coordinates[i].dom.addClass("somethingover");
}
} else {
// Nope, we did not hit any objects yet
coordinates[i].dom.removeClass("somethingover");
}
}
// Keep the last positions of the mouse coord.s
mousex = e.pageX;
mousey = e.pageY;
}
var endDragging = function(e) {
// Remove document event listeners
$(document).unbind("mousemove", continueDragging);
$(document).unbind("mouseup", endDragging);
// Check if we hit any boxes
for (var i in coordinates) {
if (mousex >= coordinates[i].left && mousex <= coordinates[i].right) {
if (mousey >= coordinates[i].top && mousey <= coordinates[i].bottom) {
// Yes, the mouse is on a droppable area
droptarget = coordinates[i].dom;
droptarget.removeClass("somethingover").addClass("dropped");
dragged.hide("fast", function() {
$(this).remove();
});
}
}
}
// Reset variables
mousex = 0;
mousey = 0;
dragged = null;
coordinates = [];
}
var startDragging = function(e) {
// Find coordinates of the droppable bounding boxes
$(".droppable").each(function() {
var lefttop = $(this).offset();
// and save them in a container for later access
coordinates.push({
dom: $(this),
left: lefttop.left,
top: lefttop.top,
right: lefttop.left + $(this).width(),
bottom: lefttop.top + $(this).height()
});
});
// When the mouse down event is received
if (e.type == "mousedown") {
dragged = $(this);
// Change the position of the draggable
dragged.css({
"left": e.pageX - (dragged.width()/2),
"top": e.pageY - (dragged.height()/2),
"position": "absolute"
});
// Bind the events for dragging and stopping
$(document).bind("mousemove", continueDragging);
$(document).bind("mouseup", endDragging);
}
}
// Start the dragging
$(".draggable").bind("mousedown", startDragging);
¿Está utilizando jQuery UI? – Purag
No, estoy usando dragg creado personalizado – user969724
Ayudaría a ver ese código. O póngalo en la pregunta o péguelo en un [jsfiddle] (http://jsfiddle.net). – Purag