jquery - form - slider html codigo
Lista ordenable jQuery: la barra de desplazamiento salta al ordenar (12)
Así es como resuelvo el problema.
$(".groups").sortable({
...
helper: function(event, ui){
lastScrollPosition = $("body").scrollTop();
},
start: function(e, ui){
// avoid scroll jump
$("body").scrollTop(lastScrollPosition);
},
});
Creé una demostración: http://pastebin.me/584b9a86d715c9ba85b7bebf0375e237
Cuando la barra de desplazamiento está en la parte inferior y arrastra elementos para ordenarlos, hace que la barra de desplazamiento salte. Parece hacer esto en FF, Safari, Chrome e IE (al menos IE8).
En Firefox en mi Mac, hace el salto cuando la barra de desplazamiento está en la parte inferior, pero también agrega un buen flash a toda la lista. Simplemente muestra toda la lista al tiempo que la desplaza hacia arriba. Creo que si descubro qué está causando el desplazamiento hacia arriba (y si puedo detenerlo), el parpadeo también se detendrá.
No me gusta saltar así b / c. Lo encuentro discordante y confuso. Sé que este es un caso de esquina, pero me gustaría arreglarlo si pudiera.
Entonces, ¿hay alguna manera de evitar que se mueva hacia arriba? Alternativamente, ¿qué está causando que se desplace hacia arriba?
Gracias
Carl M. Gregory está explicando el ''por qué esto está sucediendo'' muy claramente.
Sin embargo, la fijación de la altura no parece suficiente, ya que el contenido interno puede volverse más alto al cambiar el tamaño de la ventana.
Lo que deseo se podría hacer:
- Escuche el evento de ''inicio'' ordenable y fije la altura del contenedor clasificable
- Escuche el evento ''detener'' ordenable y ajuste la altura en automático (para asegurarse de que no haya problemas al cambiar el tamaño de la ventana)
¿Qué sucede en la práctica? El salto ocurre antes de atrapar el evento de inicio, por lo que no se puede usar
La solución alternativa: escuchar los eventos jquery mousedown y mouseup en los elementos ordenables. Es muy sencillo.
$(".sortable_item").mousedown(function(){
$(".sortable_container").height($(".sortable_container").height());
}).mouseup(function(){
$(".sortable_container").height(''auto'');
});
Sugiero que todavía consideres el punto de Carl sobre la carga de imágenes. Su respuesta vale la pena leerla.
Carl M. Gregory explica el problema a la perfección, pero creo que su solución es innecesariamente complicada.
Establecer la altura de la lista en un valor fijo corrige el problema, pero hacerlo al momento de crear la lista es demasiado temprano. Puede usar la función .mousedown()
para establecer la altura justo antes de que comience la clasificación. En este momento, ya se han cargado las posibles imágenes, por lo que no es necesario verificar sus tamaños.
Entonces el salto no ocurre, pero ahora por favor considere esto: Usted tiene múltiples listas conectadas y están organizadas verticalmente. Ahora esto sucede:
- Empiezas a arrastrar desde la lista superior
- La lista superior ahora tiene altura fija
- Mueva el elemento a la lista inferior
- La lista inferior se ajusta muy bien, porque su ''altura es
auto
- La lista superior aún tiene la misma altura fija, aunque debería ser un elemento más corto
Entonces, en algún momento, deberías devolver su altura a auto
. ¿Cuando? El mouseup
es demasiado tarde (vea https://jsfiddle.net/937vv4tx/1/ ), pero está bien, puede devolver el valor correcto casi inmediatamente después de que el salto ya no sea una amenaza. Usando el evento start()
Actualización: Pero aún desea establecer la altura en auto
en .mouseup()
porque si solo hace clic en el elemento y no comienza a arrastrarlo, todavía establece la altura fija porque el .mousedown()
ya ha sucedido.
$(''.sortable'').mousedown(function() {
// set fixed height to prevent scroll jump
// when dragging from bottom
$(this).height($(this).height());
}).mouseup(function () {
// set height back to auto
// when user just clicked on item
$(this).height(''auto'');
}).sortable({
connectWith: ''.sortable'',
placeholder: ''placeholder'',
start: function() {
// dragging is happening
// and scroll jump was prevented,
// we can set it back to auto
$(this).height(''auto'');
}
});
Este código funciona perfectamente para mí.
El problema es muy simple.
Primero configuremos el escenario. Usted tiene una lista de elementos ordenables, su página es más alta que su pantalla, por lo que tiene una barra de desplazamiento, su página está en la parte inferior, la barra de desplazamiento hasta abajo.
El problema es que arrastras un elemento que hace que jQuery lo elimine del dom y luego lo agregas en un marcador de posición. Reduzcamos la velocidad, primero elimina el elemento, ahora la lista es más corta, lo que hace que la página sea más corta, lo que hace que la barra de desplazamiento sea más corta. Luego agrega el marcador de posición, ahora la página es más larga, ahora la barra de control es más larga (pero la ventana no se desplaza hacia abajo, por lo que parece que la barra de desplazamiento saltó hacia arriba).
La mejor forma que encontré para contrarrestar esto sería asegurar que la lista ordenable tenga una altura estática, por lo que eliminar un elemento no hace que se acorte. Un método para hacer esto sería
create:function(){
jQuery(this).height(jQuery(this).height());
}
Lo anterior se invocará sobre la creación de la lista ordenable, estableciendo su altura de manera estática a su altura actual.
Si tiene imágenes en uno de los elementos clasificables, el código anterior no funcionará a menos que pre-defina las dimensiones en la etiqueta. La razón es que cuando se llama y configura la altura (), se calcula antes de que se complete la imagen. Sin dimensión, entonces la imagen no representa espacio. Una vez que la imagen se carga, ocupará espacio.
Aquí hay una forma de tener que definir las dimensiones. Simplemente cambie el tamaño de la altura de la lista cada vez que se detecte que se cargue una imagen.
create:function(){
var list=this;
jQuery(list).find(''img'').load(function(){
jQuery(list).height(jQuery(list).height());
});
}
Versión definitiva:
jQuery(document).ready(function(){
jQuery("div#todoList").sortable({
handle:''img.moveHandle'',
opacity: 0.6,
cursor: ''move'',
tolerance: ''pointer'',
forcePlaceholderSize: true,
update:function(){
jQuery("body").css(''cursor'',''progress'');
var order = jQuery(this).sortable(''serialize'');
jQuery.post("/ajax.php?do=sort&"+order,function(data){jQuery("body").css(''cursor'',''default'');});
},
create:function(){
var list=this;
resize=function(){
jQuery(list).css("height","auto");
jQuery(list).height(jQuery(list).height());
};
jQuery(list).height(jQuery(list).height());
jQuery(list).find(''img'').load(resize).error(resize);
}
});
});
Entonces, ¡complejo! Todo lo que tienes que hacer es agregar overflow: auto;
al padre (ul, #element, whatever_you_call_it), y debería funcionar. Esto garantiza que incluso si el documento cambia de altura ligeramente, al cambiar el tamaño, el desbordamiento automático retendrá la altura del elemento.
Estaba cargando mis divisibles VIA VIA Ajax en un contenedor con una altura automática.
En lugar de tratar de vincular los eventos clasificables, hice la altura automáticamente al cargar y cambiar la lista y luego establecerla en una altura estática después.
La solución de Vit es similar, pero no quería agregar una sobrecarga innecesaria haciendo esto en cada evento mousedown
y mouseup
. En cambio, solo lo hago cuando la lista está cambiando en la carga o cuando se agregan nuevos elementos (utilizo una animación slideDown
y simplemente establezco la altura en estática cuando se completa).
$("#wrapper").load("list.php",function() {
$("#wrapper").css({ "height":"auto" });
$("#wrapper").css({ "height": $("#wrapper").height() });
}
Las otras soluciones no me funcionaron cuando recargué los datos, ya que solo los pude ordenar una vez durante la carga de la página.
Mi lista / div cambia con un menú desplegable, así que puedo seleccionar listas diferentes y mi contenedor cambia el tamaño según corresponda sin el molesto salto.
Si necesita agregar elementos o volver a cargar algo, simplemente inserte esas dos líneas de código en una función y llame a la función.
¡Espero que esto ayude a alguien!
Gracias por la gran solución, pero recomiendo usar lo siguiente en su lugar:
create:function(){
var list=this;
resize=function(){
jQuery(list).css("min-height","0");
jQuery(list).height(jQuery(list).height());
};
jQuery(list).css(''min-height'', jQuery(list).height());
}
He experimentado este problema también. Sucede cuando la lista dicta la longitud de su página. Cuando comienza a ordenar, la altura de la lista cambia por una fracción de segundo, lo que hace que la página salte. Aquí hay una solución extraña, pero muy funcional para este problema:
$(''ul'').height($(''ul'').height());
Lol, parece que todavía no está parcheado 4 años después. Aquí está el ticket .
Añadiendo a la respuesta de @Carl M. Gregory, para aprovechar al máximo un contenedor dinámico en lugar de establecerlo en una altura fija, editaba el archivo core de jquery.ui.sortable.js .
Simplemente retroceda la línea 228. this._createPlaceHolder...
antes de la línea 208. this.helper.css("position", "absolute");
Gracias a Honda en el portal de boletos de jquery. Estoy usando Sortable.js versión 1.10.3.
Parece que jQuery UI 1.9.2 resolvió el problema.
Si no puede cambiar la biblioteca, hay una solución que incluye una simple operación de barra de desplazamiento. La idea es simple:
- Mantenga la posición de desplazamiento anterior cada vez que se desplace.
- Establezca el desplazamiento hacia atrás a la posición anterior cuando comience a arrastrar su elemento.
Aqui tienes;
var lastScrollPosition = 0; //variables defined in upper scope
var tempScrollPosition = 0;
window.onscroll = function () { // Up to you requirement you may change it to another elemnet e.g $("#YourPanel").onscroll
clearTimeout($.data(this, ''scrollTimer''));
$.data(this, ''scrollTimer'', setTimeout(function () {
tempScrollPosition = lastScrollPosition; // Scrolls don''t change from position a to b. They cover some numbers between a and b during the change to create a smooth sliding visual. That''s why we pick the previous scroll position with a timer of 250ms.
}, 250));
lastScrollPosition = $(document).scrollTop(); // Up to you requirement you may change it to another elemnet e.g $("#YourPanel").onscroll
};
$("#YourSortablePanel").sortable({
start: function (event, ui) {
$(document).scrollTop(tempScrollPosition);
}
});
Tuve el mismo problema al usar un contenedor div y elementos div y establecer la altura del contenedor no me ayudó, pero establecí explícitamente el desbordamiento: la propiedad auto css en el div que contiene solucionó el problema. Solo probado en Chrome sin embargo.
Tuve este problema en Chrome. Y todos los divs ordenables tenían altura fija.
El problema estaba en la position: relative
propiedad css position: relative
de estos divs. Cuando div se arrastró y eliminó de DOM, sus coordenadas se calcularon incorrectamente debido a la posición relativa.
Inherit
o absolute
posicionamiento absolute
deben usarse para los elementos clasificables.