8

Quiero tener varias clases de arrastrables, cada una correspondiente a una clase de elementos desplegables. Pero, además, quiero tener un "contenedor de basura" separado, donde todos los arrastres se puedan tirar hasta que se pueda encontrar un droppable adecuado para ellos.JQuery UI Arrastrar/soltar con múltiples ámbitos?

Ahora, esto se puede lograr fácilmente con una función de aceptación. Sin embargo, puedo tener hasta 20 clases, cada una con 30-40 arrastrables/droppables. Entonces, si utilizo una función de "aceptar" para esto, en el momento que tomo un arrastrable, mi Chrome se congela mientras ejecuta las pruebas de cada pantalla desplegable: (

Esto se puede resolver si utilizo el 'alcance' propiedad, ya que parece estar usando una forma diferente. Sin embargo, cuando uso un alcance, parece que no puedo implementar el concepto de "cubo de basura", ya que solo puede tener un alcance!

¿Hay alguna manera? a by-pass este problema? dar a los draggables más de un ámbito, o dar el cubo de la basura muchos ámbitos? o tal vez alguna otra solución que no se le ocurre?

+1

hola. ¿puedes publicar algún código para que podamos ver lo que tienes hasta ahora? – chrisvillanueva

Respuesta

7

Internamente jQuery UI se ejecutará el siguiente código cada vez que inicie arrastrando un draggable a d etermine que droppable s son elegibles para recibir el draggable.

var m = $.ui.ddmanager.droppables[t.options.scope] || []; 
var type = event ? event.type : null; // workaround for #2317 
var list = (t.currentItem || t.element).find(":data(droppable)").andSelf(); 

droppablesLoop: for (var i = 0; i < m.length; i++) { 

    if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted 
    for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item 
    m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue;         //If the element is not visible, continue 

    if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables 

    m[i].offset = m[i].element.offset(); 
    m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 

} 

Como se puede ver el código no es trivial y explicaría por qué se está viendo un rendimiento lento cada vez que inicia arrastrando.

Una cosa a tener en cuenta es que lo primero que se comprueba en el droppablesLoop es si el droppable está deshabilitado.

Por lo tanto, para aumentar el rendimiento, siempre puede desactivar manualmente los widgets droppable apropiados que le harán salirse rápidamente del bloque de código anterior. Puede hacerlo utilizando el evento start en el draggable, que se disparará primero.

$('.draggable').draggable({ 
    start: function() { 
     $('.invalid-droppable-elements').droppable('option', 'disabled', true); 
    }, 
    stop: function() { 
     $('.invalid-droppable-elements').droppable('option', 'disabled', false); 
    } 
}); 

Esto hace esencialmente a implementar la lógica accept/scope sí mismo y el impacto en el rendimiento depende de su algoritmo. Sin embargo, no debería ser tan malo implementarlo. La razón por la que los complementos son tan lentos como son es porque tienen que manejar MUCHAS situaciones diferentes.

jQuery UI no admite la adición de múltiples ámbitos a los elementos individuales draggable/droppable, pero puede rodar esa funcionalidad por su cuenta.

Puse un ejemplo para mostrar esto aquí - http://jsfiddle.net/tj_vantoll/TgQTP/1/.

+1

Esto realmente tuvo un buen efecto en el rendimiento, pero aún es muy delgado en comparación con el uso del alcance ... De hecho, tenía todas las etiquetas desplegables desactivadas, excepto la bandeja y habilité solo las que necesitaba. ¿No hay forma de hacer que algo pertenezca a más de un ámbito? – Gilthans

+1

Edité mi respuesta para responder a su pregunta. La respuesta corta es que no jQuery UI no es compatible con múltiples ámbitos, pero es bastante fácil de implementar por su cuenta. –

+0

Esto es genial, pero para cualquiera que se pregunte, parece que hay un poco de "complejidad" extra con el '.each'. A menos que me falta algo, simplemente puede hacer referencia a '$ ('. Draggable')' y mover la asignación de 'var scope' a' start' – MCB

Cuestiones relacionadas