css - los - obtener el primer hijo de un elemento jquery
¿Cómo reparar los ayudantes que se pueden colocar erróneamente y que se pueden colocar para los ordenamientos conectados(parcialmente causados por elementos padre posicionados en posición flotante/relativa)? (3)
ver https://jsfiddle.net/tsLcjw9c/1/
Puse un ancho fijo en la lista de juegos de arrastrar (100px) para que el asistente que se puede arrastrar tenga el mismo ancho que los elementos de la lista, esto evita el desplazamiento horizontal inicial.
el gran desplazamiento horizontal que obtuviste mientras arrastras el contenedor clasificable parece ser un error en la interfaz de usuario de jquery pero también parece ser exactamente el 100% del ancho del contenedor clasificable, por lo que agregué el siguiente CSS:
.sortable .ui-draggable-dragging:not(.ui-sortable-helper){
margin-left:100%;
}
El desplazamiento vertical que obtuvo después de ingresar y salir de las listas clasificables parecía ser causado por el margen de los elementos arrastrables de 4px, que eliminé. Puede alcanzar el mismo efecto con un borde transparente y un tamaño de caja: border-box; o agregue un relleno y establezca background-clip a padding-box.
Por último, la animación de 600 ms que quería que ocurriera al eliminar los elementos sucedió de forma extraña en mi navegador (Chrome), fue a 2 ubicaciones diferentes antes de finalmente animar hacia el lugar correcto. Es por eso que ahora deshabilité la animación. Puede intentar anular el evento drop en el jQuery ordenable, para que pueda animarlo manualmente hacia la ubicación correcta.
Aquí el código jsfiddle:
html
<div class=''container-fluid''>
<div class=''row''>
<div class=''col-xs-6''>
<div id=''sortables''>
<div class=''sortable-container''>
<ul class=''sortable''>
<li>sortable 1</li>
<li>sortable 2</li>
<li>sortable 3</li>
<li>sortable 4</li>
<li>sortable 5</li>
<li>sortable 6</li>
</ul>
</div>
<div class=''sortable-container''>
<ul class=''sortable''>
<li>sortable 1</li>
<li>sortable 2</li>
<li>sortable 3</li>
<li>sortable 4</li>
<li>sortable 5</li>
<li>sortable 6</li>
</ul>
</div>
<div class=''sortable-container''>
<ul class=''sortable''>
<li>sortable 1</li>
<li>sortable 2</li>
<li>sortable 3</li>
<li>sortable 4</li>
<li>sortable 5</li>
<li>sortable 6</li>
</ul>
</div>
</div>
</div>
<div class=''col-xs-6''>
<ul id=''draggables''>
<li class=''draggable''>draggable 1</li>
<li class=''draggable''>draggable 2</li>
<li class=''draggable''>draggable 3</li>
</ul>
</div>
</div>
</div>
jquery
$(''.sortable'').sortable({
connectWith: ''.sortable'',
revert: 0,
forcePlaceholderSize: true,
placeholder: ''ui-sortable-placeholder'',
tolerance: ''pointer''
}).disableSelection();
$(''.draggable'').draggable({
connectToSortable: ''.sortable'',
helper: ''clone'',
revert: false
}).disableSelection();
css
.sortable-container {
display: inline-block;
width: 100px;
vertical-align: top;
}
.sortable {
cursor: move;
margin: 0;
padding: 0;
list-style-type: none;
vertical-align: top;
border: 1px solid #000;
}
.ui-sortable-placeholder {
background: #ff0000;
}
#draggables {
margin: 0;
padding: 0;
list-style-type: none;
}
.draggable {
cursor: move;
color: #fff;
background: #5dd1ff;
width:100px;
max-width:100%;
}
.sortable .ui-draggable-dragging:not(.ui-sortable-helper){
margin-left:100%;
}
Prefacio
Estoy experimentando un problema donde el auxiliar que se puede arrastrar se está compensando de forma incorrecta, cuando se usan arrastrables + ordenables que se colocan en elementos primarios flotantes con posición relativa. Los elementos principales flotantes son columnas de Bootstrap, donde se colocan múltiples listas ordenables en una columna y una lista de juegos de arrastre en otra.
Ejemplo
Aquí hay un fragmento de ejemplo que funciona
$(''.sortable'').sortable({
connectWith: ''.sortable'',
revert: 600,
forcePlaceholderSize: true,
placeholder: ''ui-sortable-placeholder'',
tolerance: ''pointer''
}).disableSelection();
$(''.draggable'').draggable({
connectToSortable: ''.sortable'',
helper: ''clone'',
revert: true
}).disableSelection();
.sortable-container {
display: inline-block;
width: 100px;
vertical-align: top;
}
.sortable {
cursor: move;
margin: 0;
padding: 0;
list-style-type: none;
vertical-align: top;
border: 1px solid #000;
}
.ui-sortable-placeholder {
background: #ff0000;
}
#draggables {
margin: 0;
padding: 0;
list-style-type: none;
}
.draggable {
margin: 4px;
cursor: move;
color: #fff;
background: #5dd1ff;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<div class=''container-fluid''>
<div class="row">
<div class="col-xs-3">
<p>foo</p>
<p>bar</p>
</div>
<div class="col-xs-3">
<p>foo</p>
<p>bar</p>
</div>
<div class="col-xs-6">
<p>foo</p>
<p>bar</p>
</div>
</div>
<div class=''row''>
<div class=''col-xs-6''>
<div id=''sortables''>
<div class=''sortable-container''>
<ul class=''sortable''>
<li>sortable 1</li>
<li>sortable 2</li>
<li>sortable 3</li>
<li>sortable 4</li>
<li>sortable 5</li>
<li>sortable 6</li>
</ul>
</div>
<div class=''sortable-container''>
<ul class=''sortable''>
<li>sortable 1</li>
<li>sortable 2</li>
<li>sortable 3</li>
<li>sortable 4</li>
<li>sortable 5</li>
<li>sortable 6</li>
</ul>
</div>
<div class=''sortable-container''>
<ul class=''sortable''>
<li>sortable 1</li>
<li>sortable 2</li>
<li>sortable 3</li>
<li>sortable 4</li>
<li>sortable 5</li>
<li>sortable 6</li>
</ul>
</div>
</div>
</div>
<div class=''col-xs-6''>
<ul id=''draggables''>
<li class=''draggable''>draggable 1</li>
<li class=''draggable''>draggable 2</li>
<li class=''draggable''>draggable 3</li>
</ul>
</div>
</div>
</div>
Actualización 16 de noviembre de 2015 Modifiqué el ejemplo del código para reflejar mejor mi contexto de uso real, donde hay más filas encima de la que contiene los draggables / sortables.
un screencast y una imagen fija que muestra lo que sucede
Explicación adicional
Al arrastrar uno de los arrastrables desde la columna del lado derecho sobre una de las listas ordenables en el lado izquierdo, y no soltarlo, sino arrastrarlo más lejos del cuadro delimitador de listas ordenables, el ayudante se está posicionando incorrectamente, se desplaza una unos pocos cientos de píxeles a la izquierda, como si estuviera incorporando incorrectamente algún tipo de compensación (parece que podría ser la posición original que se puede arrastrar).
Curiosamente, esto no ocurre cuando los juegos de arrastre se colocan en el mismo elemento principal que los ordenables, al menos no se desplazará horizontalmente, sino verticalmente al mover el cursor arrastrable hacia arriba / abajo o hacia la izquierda / derecha dentro / fuera de la lista ordenable .
El desplazamiento horizontal está de alguna manera relacionado con los elementos primarios con posición flotante / relativa, deshabilitar el posicionamiento flotante o relativo lo corrige. Sin embargo, me gustaría mantener esto como está, y encontrar otra solución / solución en su lugar. El desplazamiento vertical también ocurre cuando el posicionamiento flotante / relativo no está involucrado, así que supongo que hay un poco más de este problema.
Actualización 15 de noviembre de 2015 - Cambios en la interfaz de usuario de jQuery
Parece que jQuery UI 1.11.4 cambió el comportamiento un poco, ahora no cambiará inmediatamente horizontalmente en el momento en que abandone el cuadro delimitador de un ordenable, pero primero tiene que moverse entre dos o más ordenables. Aparte de eso, el comportamiento de los errores parece no haber cambiado.
Actualización 16 de noviembre de 2015 - appendTo
option
Inicialmente traté de usar appendTo
una solución, ya que de esa manera el helper se mantendría fuera de las listas, y si bien esto es cierto para mi código de ejemplo original, no funcionará con el código de ejemplo actualizado, donde hay más filas colocados por encima de los que tienen los juegos de arrastre / sortables, están haciendo que el ayudante se mueva verticalmente.
Pregunta
¿Alguien sabe dónde se origina exactamente el desplazamiento horizontal problemático, y cómo solucionarlo mientras se usan los elementos principales posicionados flotantes / relativos?
¿Y qué ocurre con la compensación vertical, dado que esto sucede también en la demostración jQuery UI , me hace pensar que se trata de un error que no está relacionado con el diseño de los elementos principales?
Actualización 15 Nov 2015 - Problema de compensación vertical ubicado
El desplazamiento vertical parece tener que ver con el margen aplicado en los juegos de arrastre, sin eso parece funcionar bien.
He informado de ambos como errores, pero aún estoy buscando una solución / solución alternativa que pueda aplicar yo mismo hasta que esto se solucione o no en la biblioteca.
http://bugs.jqueryui.com/ticket/14822
http://bugs.jqueryui.com/ticket/14806
Lo extraño es que parece funcionar mejor con jquery-ui 10.4 . La diferencia es que en 10.4 el helper que se puede arrastrar permanece en su div original, y se clona en los ordenables pero está oculto. Entonces, los cálculos son más fáciles de hacer.
En 11.4, el ayudante se agrega al ordenamiento sobre el que se arrastra, lo que hace que los cálculos de compensación precisos sean difíciles de seguir. Constantemente tiene que cambiar el desplazamiento padre y realizar un seguimiento de qué orden es, en qué orden se encontraba, la posición del ordenable, etc. Y claramente hay un error allí.
Una solución simple sería obtener el plugin connectToSortable de 10.4. Deberá verificar los efectos secundarios no deseados, pero rápidamente parece estar funcionando. Puede usar un nombre diferente para que conserve el original. Me gusta esto:
$.ui.plugin.add("draggable", "connectToSortable104", {
// You take the whole connectToSortable plugin from
// here: https://code.jquery.com/ui/1.10.4/jquery-ui.js
// In 11.4 you''ll need to add draggable parameter
// for example: to the event methods,
// start: function(event, ui, draggable)
...
Ver http://jsfiddle.net/gsnojkbc/2/
EDITAR:
No creo que el div adicional sea lo que causa el problema, es realmente un error con la forma en que funciona connectToStayable en jquery 11.4 que está causando el problema. Para permitir el movimiento del ayudante en los sortables y seguir haciendo un seguimiento de la compensación adecuada, necesita reajustar algunos datos cada vez que el ayudante cambia div. Hay dos defectos en la forma en que se hace:
El primero es que hay un método refreshOffsets que es común a otros eventos en el que se puede arrastrar . Se usa, por ejemplo, cuando haces clic en un archivo arrastrable. Y entonces intenta calcular el desplazamiento basado en el clic. Pero al llamar a refreshOffsets desde el evento ordenable, confunde el desplazamiento del clic. Esto se puede resolver cambiando el método refreshOffsets para no tener en cuenta el evento.pageX y Y. De esta manera:
$.ui.draggable.prototype._refreshOffsetsSortable = function(event, draggable){
this.offset = {
top: this.positionAbs.top - this.margins.top,
left: this.positionAbs.left - this.margins.left,
scroll: false,
parent: this._getParentOffset(),
relative: this._getRelativeOffset()
};
this.offset.click = draggable.offset.click;
}
El otro problema ocurre porque tienes muchos sortables . Básicamente, la otra operación que debe realizarse es cambiar el desplazamiento padre. La forma en que se hace ahora es que guarda el padre anterior. Normalmente funciona, pero si te mueves demasiado rápido, la secuencia hace que el padre guardado sea ordenable y no el padre original. Puede solucionar esto guardando el elemento principal en el inicio de arrastre, que en cualquier caso parece tener más sentido. Me gusta esto:
$.ui.plugin.add( "draggable", "connectToSortableFixed", {
start: function( event, ui, draggable ) {
var uiSortable = $.extend( {}, ui, {
item: draggable.element
});
draggable._parent = this.parent();
...
Vea aquí: http://jsfiddle.net/24a8q49j/1/
Una solución simple de solo JavaScript es almacenar el desplazamiento en el mouse cuando se inicia el arrastre y luego forzar al ui.helper
a tener el mismo desplazamiento al mouse, siempre:
[...]
var offset_start = {};
$(''.draggable'').draggable({
connectToSortable: ''.sortable'',
helper: ''clone'',
revert: true,
start: function(e, ui) {
offset_start = {
x: ui.position.left - e.pageX,
y: ui.position.top - e.pageY
}
},
drag: function(e, ui) {
ui.position.top = e.pageY + offset_start.y
ui.position.left = e.pageX + offset_start.x
}
}).disableSelection();
Vea el jsfiddle actualizado .
Para el caso simple, esta es una solución fácil, pero requiere más trabajo si introduce fronteras (donde el ayudante no puede salir), etc.
Editar: Para su fragmento, se me ocurrió otra solución (porque la otra no funciona como se esperaba, más difícil obtener las compensaciones iniciales de lo que pensaba ...): simplemente fuerce el elemento para permanecer en el puntero del mouse, independientemente de la inicial compensación después de agregar el ayudante al cuerpo. No es 100% agradable, porque al comenzar a arrastrarlo podría "saltar" al mouse, pero luego se queda allí al menos ...
$(''.draggable'').draggable({
connectToSortable: ''.sortable'',
helper: ''clone'',
revert: ''invalid'',
appendTo: ''body'',
drag: function(e, ui) {
if (!ui.helper.parent().is(''body'')) {
ui.helper.appendTo($(''body''));
}
ui.position.top = e.pageY - 10;
ui.position.left = e.pageX - 25;
}
}).disableSelection();
$(''.sortable'').sortable({
connectWith: ''.sortable'',
revert: 600,
forcePlaceholderSize: true,
placeholder: ''ui-sortable-placeholder'',
tolerance: ''pointer''
}).disableSelection();
$(''.draggable'').draggable({
connectToSortable: ''.sortable'',
helper: ''clone'',
revert: ''invalid'',
appendTo: ''body'',
scroll: false,
drag: function(e, ui) {
if (!ui.helper.parent().is(''body'')) {
ui.helper.appendTo($(''body''));
}
ui.position.top = e.pageY - 15;
ui.position.left = e.pageX - 25;
}
}).disableSelection()
.sortable-container {
display: inline-block;
width: 100px;
vertical-align: top;
}
.sortable {
cursor: move;
margin: 0;
padding: 0;
list-style-type: none;
vertical-align: top;
border: 1px solid #000;
}
.ui-sortable-placeholder {
background: #ff0000;
}
#draggables {
margin: 0;
padding: 0;
list-style-type: none;
}
.draggable {
margin: 4px;
cursor: move;
color: #fff;
background: #5dd1ff;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<div class=''container-fluid''>
<div class="row">
<div class="col-xs-3">
<p>foo</p>
<p>bar</p>
</div>
<div class="col-xs-3">
<p>foo</p>
<p>bar</p>
</div>
<div class="col-xs-6">
<p>foo</p>
<p>bar</p>
</div>
</div>
<div class=''row''>
<div class=''col-xs-6''>
<div id=''sortables''>
<div class=''sortable-container''>
<ul class=''sortable''>
<li>sortable 1</li>
<li>sortable 2</li>
<li>sortable 3</li>
<li>sortable 4</li>
<li>sortable 5</li>
<li>sortable 6</li>
</ul>
</div>
<div class=''sortable-container''>
<ul class=''sortable''>
<li>sortable 1</li>
<li>sortable 2</li>
<li>sortable 3</li>
<li>sortable 4</li>
<li>sortable 5</li>
<li>sortable 6</li>
</ul>
</div>
<div class=''sortable-container''>
<ul class=''sortable''>
<li>sortable 1</li>
<li>sortable 2</li>
<li>sortable 3</li>
<li>sortable 4</li>
<li>sortable 5</li>
<li>sortable 6</li>
</ul>
</div>
</div>
</div>
<div class=''col-xs-6''>
<ul id=''draggables''>
<li class=''draggable''>draggable 1</li>
<li class=''draggable''>draggable 2</li>
<li class=''draggable''>draggable 3</li>
</ul>
</div>
</div>
</div>