Estoy usando jQuery que se puede arrastrar y soltar para un sistema de planificación del trabajo que estoy desarrollando. Los usuarios arrastran trabajos a un día o usuario diferente, y luego los datos se actualizan mediante una llamada ajax.
Todo funciona bien, excepto cuando me desplazo hacia abajo en la página principal (los trabajos aparecen en un planificador semanal grande que excede la parte inferior de la ventana de mi navegador). Si intento arrastrar un elemento que se puede arrastrar aquí, el elemento aparece sobre el cursor del mouse con la misma cantidad de píxeles que he desplazado hacia abajo. El estado de desplazamiento sigue funcionando bien y la funcionalidad está funcionando pero no se ve bien.
Estoy usando jQuery 1.6.0 y jQuery UI 1.8.12.
Estoy seguro de que necesito agregar una función de compensación, pero no sé dónde aplicarla o si hay una manera mejor. Aquí está mi .draggable()
código de inicialización:
$('.job').draggable({
zIndex: 20,
revert: 'invalid',
helper: 'original',
distance: 30,
refreshPositions: true,
});
¿Alguna idea de lo que puedo hacer para solucionar este problema?
Respuestas:
Este podría ser un informe de error relacionado, existe desde hace bastante tiempo: http://bugs.jqueryui.com/ticket/3740
Parece suceder en todos los navegadores que probé (Chrome, FF4, IE9). Hay varias formas de solucionar este problema:
1. Úselo
position:absolute;
en su css. Los elementos absolutamente posicionados no parecen verse afectados.2. Asegúrese de que el elemento padre (evento si es el cuerpo) se haya
overflow:auto;
establecido. Mi prueba mostró que esta solución corrige la posición, pero deshabilita la función de desplazamiento automático. Aún puede desplazarse usando la rueda del mouse o las teclas de flecha.3. Aplique manualmente la corrección sugerida en el informe de error anterior y pruebe a fondo si causa otros problemas.
4. Espere una solución oficial. Está programado para jQuery UI 1.9, aunque se ha pospuesto varias veces en el pasado.
5. Si está seguro de que sucede en todos los navegadores, puede poner estos trucos en los eventos de los draggables afectados para corregir los cálculos. Sin embargo, hay muchos navegadores diferentes para probar, por lo que solo debe usarse como último recurso:
$('.drag').draggable({ scroll:true, start: function(){ $(this).data("startingScrollTop",$(this).parent().scrollTop()); }, drag: function(event,ui){ var st = parseInt($(this).data("startingScrollTop")); ui.position.top -= $(this).parent().scrollTop() - st; } });
fuente
helper: "clone"
. bugs.jqueryui.com/ticket/9315 Nivel bloqueador , un punto por encima importante. tj.vantoll dice "6 arreglos arrastrables que aterrizaron en 1.10.3 podrían ser sospechosos". El ejemplo más simple hasta ahora: jsfiddle.net/7AxXEEsta solución funciona sin ajustar el posicionamiento de nada, simplemente clona el elemento y lo coloca absolutamente posicionado.
$(".sidebar_container").sortable({ .. helper: function(event, ui){ var $clone = $(ui).clone(); $clone .css('position','absolute'); return $clone.get(0); }, ... });
El ayudante puede ser una función que necesita devolver el elemento DOM para arrastrar.
fuente
Esto funcionó para mí:
start: function (event, ui) { $(this).data("startingScrollTop",window.pageYOffset); }, drag: function(event,ui){ var st = parseInt($(this).data("startingScrollTop")); ui.position.top -= st; },
fuente
"1.11.0"
Perdón por escribir otra respuesta. Como no pude usar ninguna de las soluciones en la respuesta anterior, busqué mucho en Google e hice muchas ediciones menores frustrantes antes de encontrar otra solución razonable.
Este problema parece ocurrir siempre que cualquiera de los elementos principales se haya
position
establecido en 'relativo'. Tuve que reorganizar mi marcado y alterar mi CSS, pero al eliminar esta propiedad de todos los padres, pude empezar a.sortable()
trabajar correctamente en todos los navegadores.fuente
position: relative;
en cualquier padre hace que esto suceda.position: relative;
el cual tuvo que ser retirado .. elementos primarios entre los que pueden arrastrarse y el cuerpo parece no hacer problemes aquí ..Parece que este error aparece muy a menudo y cada vez hay una solución diferente. Nada de lo anterior, o cualquier otra cosa que encontré en Internet, funcionó. Estoy usando jQuery 1.9.1 y Jquery UI 1.10.3. Así es como lo arreglé:
$(".dragme").draggable({ appendTo: "body", helper: "clone", scroll: false, cursorAt: {left: 5, top: 5}, start: function(event, ui) { if(! $.browser.chrome) ui.position.top -= $(window).scrollTop(); }, drag: function(event, ui) { if(! $.browser.chrome) ui.position.top -= $(window).scrollTop(); } });
Funciona en FF, IE, Chrome, todavía no lo he probado en otros navegadores.
fuente
Borro el desbordamiento:
html {overflow-y: scroll; background: #fff;}
¡Y funciona perfectamente!
fuente
Este error se movió a http://bugs.jqueryui.com/ticket/6817 y, a partir de hace unos 5 días (16 de diciembre de 2013 o aproximadamente) parece que finalmente se ha solucionado. La sugerencia en este momento es usar la última compilación de desarrollo de http://code.jquery.com/ui/jquery-ui-git.js o esperar la
versión 1.10.4 que debería contener esta corrección.Editar: Parece que esta solución ahora podría ser parte de http://bugs.jqueryui.com/ticket/9315 que no está programado para eliminarse hasta la versión 1.11. El uso de la versión de control de fuente vinculada anterior de jQuery parece solucionar el problema para mí y @Scott Alexander (comentario a continuación).
fuente
Parece notable que este error no se haya solucionado durante tanto tiempo. Para mí es un problema en Safari y Chrome (es decir, los navegadores webkit) pero no en IE7 / 8/9 ni en Firefox, que funcionan bien.
Encontré que la configuración absoluta o fija, con o sin! Importante, no ayudó, así que al final agregué una línea a mi función de controlador de arrastre:
ui.position.top += $( 'body' ).scrollTop();
Esperaba tener que hacer esa línea específica de webkit, pero curiosamente funcionó bien en todas partes. (Espere un comentario mío pronto diciendo 'er no, en realidad arruinó todos los demás navegadores').
fuente
lo que he hecho es:
$("#btnPageBreak").draggable( { appendTo: 'body', helper: function(event) { return '<div id="pageBreakHelper"><img id="page-break-img" src="page_break_cursor_red.png" /></div>'; }, start: function(event, ui) { }, stop: function(event, ui) { }, drag: function(event,ui){ ui.helper.offset(ui.position); } });
fuente
No estoy completamente seguro de que esto funcione en todos los casos, pero esta solución simplemente funcionó para mí en todas las situaciones que tuve que probar (y donde las soluciones propuestas anteriores dadas aquí y en otros lugares fallaron)
(function($){ $.ui.draggable.prototype._getRelativeOffset = function() { if(this.cssPosition == "relative") { var p = this.element.position(); return { top: p.top - (parseInt(this.helper.css("top"),10) || 0)/* + this.scrollParent.scrollTop()*/, left: p.left - (parseInt(this.helper.css("left"),10) || 0)/* + this.scrollParent.scrollLeft()*/ }; } else { return { top: 0, left: 0 }; } }; }(jQuery));
(Lo envié al rastreador jQuery.ui para ver qué piensan al respecto ... sería genial si ese error de 4 años pudiera finalmente corregirse: /)
fuente
Estoy usando JQuery arrastrable en Firefox 21.0 y estoy teniendo el mismo problema. El cursor permanece una pulgada por encima de la imagen de ayuda. Creo que este es un problema en el propio Jquery que aún no se ha resuelto. Encontré una solución a este problema, que está usando la propiedad "cursorAt" del draggable. Lo usé de la siguiente manera, pero uno puede cambiar esto de acuerdo con sus requisitos.
$('.dragme').draggable({ helper: 'clone', cursor: 'move', cursorAt: {left: 50, top: 80} });
Nota: Esto se aplicará a todos los navegadores, por lo que después de usar este código, verifique su página en todos los navegadores para obtener las posiciones izquierda y superior correctas.
fuente
Esto es lo que me funcionó, después de adaptar todo lo que he leído sobre el problema.
$(this).draggable({ ... start: function (event, ui) { $(this).data("scrollposTop", $('#elementThatScrolls').scrollTop(); $(this).data("scrollposLeft", $('#elementThatScrolls').scrollLeft(); }, drag: function (event, ui) { ui.position.top += $('#elementThatScrolls').scrollTop(); ui.position.left += $('#elementThatScrolls').scrollLeft(); }, ... });
* elementThatScrolls es el padre o el antepasado con overflow: auto;
Calcula la posición del elemento de desplazamiento y se suma a la posición del ayudante cada vez que se mueve / arrastra.
Espero que ayude a alguien, ya que perdí mucho tiempo en esto.
fuente
Esto parece hacer la solución sin necesidad de usar la posición: absoluta en el padre :)
$("body").draggable({ drag: function(event, ui) { return false; } });
fuente
Me las arreglé para solucionar el mismo problema al agregar
display: inline-block
a los arrastradosAgregar
position: relative
NO funcionó para mí (jQuery lo anula conposition: absolute
el inicio de arrastre)Versiones jQuery usadas:
fuente
position: relative
puede haber funcionado si lo movió a un elemento contenedor de nivel superior. Sé que no ayuda ahora, pero solo como referencia y tal vez para un futuro desarrollador con problemas.Tuve el mismo problema y descubrí que todo esto se debía a una clase "navbar-fixed-top" de la barra de navegación de arranque con posición fija, que se mueve hacia abajo en mi
<body>
60px por debajo de<html>
parte superior. Entonces, cuando estaba moviendo formularios que se pueden arrastrar en mi sitio, el cursor apareció 60px en la parte superior del formulario.Puede ver que en la herramienta de depuración de Chrome, en la interfaz de Elementos, haga clic en el
<body>
etiqueta y verá un espacio entre la parte superior y el cuerpo.Dado que estoy usando esta barra de navegación en todas mis aplicaciones y no quería modificar mi llamada de inicialización para arrastrar (según el procedimiento de DarthJDG) para cada formulario. Decidí extender el widget arrastrable de esta manera y simplemente agregar un yOffset en mi inicialización arrastrable.
(function($) { $.widget("my-ui.draggable", $.ui.draggable, { _mouseDrag: function(event, noPropagation) { //Compute the helpers position this.position = this._generatePosition(event); this.positionAbs = this._convertPositionTo("absolute"); //Call plugins and callbacks and use the resulting position if something is returned if (!noPropagation) { var ui = this._uiHash(); if(this._trigger('drag', event, ui) === false) { this._mouseUp({}); return false; } this.position = ui.position; } // Modification here we add yoffset in options and calculation var yOffset = ("yOffset" in this.options) ? this.options.yOffset : 0; if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top-yOffset+'px'; if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); return false; } }); })(jQuery);
Ahora, cuando inicializo el elemento / formulario arrastrable en un sitio usando la barra de navegación de arranque:
// Make the edit forms draggable $("#org_account_pop").draggable({handle:" .drag_handle", yOffset: 60});
Por supuesto, tendrá que experimentar para determinar el yOffset correcto según su propio sitio.
Gracias de todos modos a DarthJDG que me indicó la dirección correcta. ¡Salud!
fuente
Dejé de usar jQueryUi arrastrable y me mudé para usar un mejor complemento llamado jquery.even.drag , un tamaño de código mucho más pequeño, sin toda la basura que tiene jQueryUI.
Hice una página de demostración usando este complemento dentro de un contenedor que tiene una posición: fija
Manifestación
Espero que esto ayude a alguien, porque este problema es GRANDE.
fuente
Tuve un problema similar, solo que con IE 10 en particular ejecutándose en Windows 8. Todos los demás navegadores funcionaron bien. Quitar cursorAt: {top: 0} resolvió el problema.
fuente
Probé varias respuestas aquí, incluida la actualización de jQuery y descubrí que esto funcionó para mí. Probé esto en los últimos Chrome e IE. Supongo que esto será un problema con diferentes soluciones según el diseño de su interfaz de usuario.
$('{selector}').draggable({ start: function(event, ui) { ui.position.top -= $(document).scrollTop(); }, drag: function(event, ui) { ui.position.top -= $(document).scrollTop(); } });
fuente
¿Por qué no tomar la posición del cursor? Estoy usando el complemento ordenable y lo soluciono con este código:
sort: function(e, ui) { $(".ui-sortable-handle.ui-sortable-helper").css({'top':e.pageY}); }
fuente
Utilice
appendTo: "body'
y establezca la posición concursorAt
. Esto funciona bien para mí.$('.js-tire').draggable tolerance: 'fit', appendTo: 'body', cursor: 'move', cursorAt: top: 15, left: 18 helper: (event) -> $('<div class="tire-icon"></div>').append($('<img src="/images/tyre_32_32.png" />')) start: (event, ui) -> if $(event.target).hasClass 'in-use' $('.js-send-to-maintenance-box').addClass 'is-highlighted' else $('.ui-droppable').addClass 'is-highlighted' stop: (event, ui) -> $('.ui-droppable') .removeClass 'is-highlighted' .removeClass 'is-dragover'
fuente
Estoy usando un navegador pegajoso en la parte superior y pensé que eso era lo que estaba causando el problema de desplazamiento que todos los demás parecen tener. Probé la idea de todos los demás con cursorAt, probé la contención y nada funcionó EXCEPTO desarmar mi desbordamiento de html en el CSS. Es una locura cómo un poco de CSS arruinará todo. Esto es lo que hice y funciona como un encanto:
html { overflow-x: unset; } body { overflow-x: hidden; }
fuente