в jQuery пользовательского интерфейса сортировки вспомогательный элемент прокрутки смещение проблема Firefox
У меня проблема с сортируемым списком jQuery UI 1.7.2 в Firefox 3.6, IE7-8 работает нормально. Когда я прокручиваю немного вниз, вспомогательный элемент, кажется, имеет смещение той же высоты, что и я
прокрутите вниз от указателя мыши, что делает невозможным увидеть, какой элемент вы изначально начали перетаскивать.
Как это исправить или обойти проблему? Если нет исправления, что такое действительно хороший альтернативный плагин с возможностью перетаскивания?
вот мои параметры инициализации сортируемый.
$("#sortable").sortable( {placeholder: 'ui-state-highlight' } );
$("#sortable").disableSelection();
15 ответов:
Я видел эту проблему и смог решить ее, удалив CSS rule position:relative из одного из содержащих divs на моей странице. См. также: http://forum.jquery.com/topic/sortable-offset-when-element-is-dragged-and-page-scrolled-down-ff
Если вы хотите предотвратить обнюхивание браузера, единственным решением CSS является установка стиля ul или контейнера в
overflow: auto. Если вы посмотрите на источник через firebug, это то, как jQuery делает это в своем пример.
используя
overflow: auto;не был вариант для меня. Я смог обойти эту проблему с этимsortобработчик событий:$(...).sortable({ ... sort: function(event, ui) { var $target = $(event.target); if (!/html|body/i.test($target.offsetParent()[0].tagName)) { var top = event.pageY - $target.offsetParent().offset().top - (ui.helper.outerHeight(true) / 2); ui.helper.css({'top' : top + 'px'}); } }, ... });это не идеально, но это не требует браузера нюхать. Протестировано в IE8, Chrome и Firefox.
Edit: это использование jQuery 1.10.0 и jQuery UI 1.10.3.
Я также имел эту проблему и исправил ее с помощью следующего кода:
var wscrolltop = 0; $sortable_elements.sortable({ start: function(event, ui) { wscrolltop = $(window).scrollTop(); }, sort: function(event, ui) { ui.helper.css({'top' : ui.position.top + wscrolltop + 'px'}); } });я обнаружил, что все еще есть проблема, если вы прокручиваете свой сортируемый элемент. Может быть, у кого-то есть решение для этого?
обновление: Исправление:
$sortable_elements.sortable({ connectWith: '#personal-favs ul.fitems', sort: function(event, ui) { ui.helper.css({'top' : ui.position.top + $(window).scrollTop() + 'px'}); } });но все же-если вы выходите из списка, сортировка-событие, кажется, останавливается.
Вам также нужно учитывать тот факт, что это специфично для firefox, вот фрагмент, который я использую - я получил правильный путь от решения Харриса. Я столкнулся с этой проблемой без использования помощника, когда сортируемый был в относительно расположенном контейнере.
var options = { handle: '.mover', update:updateSorting }; var userAgent = navigator.userAgent.toLowerCase(); if(userAgent.match(/firefox/)) { options["start"] = function (event, ui) { ui.item.css('margin-top', $(window).scrollTop() ); }; options["beforeStop"] = function (event, ui) { ui.item.css('margin-top', 0 ); }; } $("#" + list_id+"").sortable(options); $("#" + list_id+"").disableSelection();вы также можете сделать эту проверку на сервере, а затем иметь 2 разных вызова в зависимости от браузера.
мне удалось выяснить исправление для этого:
$( "items" ).sortable({ start: function (event, ui) { if( ui.helper !== undefined ) ui.helper.css('position','absolute').css('margin-top', $(window).scrollTop() ); }, beforeStop: function (event, ui) { if( ui.offset !== undefined ) ui.helper.css('margin-top', 0); }, placeholder: 'placeholder-class' });в принципе, вам нужно прослушать событие "start" сортируемого, чтобы добавить текущее значение scrollTop() браузера в позицию помощника, а затем вам нужно прослушать событие "beforeStop" сортируемого, чтобы удалить это смещение до того, как элемент официально будет помещен обратно в список на его новой позиции.
надеюсь, что это полезно для кого-то!
Я заставляю полосы прокрутки на моем сайте, поэтому эта прокручиваемая проблема смещения возникает из-за наличия
html { overflow-y: scroll }в моем CSS.когда я включаю и выключаю прокрутку, я использовал следующее, чтобы обойти его. Я только протестировал его в IE8, FF12 и Chrome...
turnSortingOnOff:function(e) { e.preventDefault(); if (stopOrdering()) { // get rid of the hacky css on the html element $('html').css({ 'overflow-y': '' }); $('html').css({ 'margin-right': '' }); elmt.sortable('disable'); } else if (startOrdering()) { // if the body is smaller than the window // then there aren't any scrollbars // in which case, add a right hand margin of 16px // to the html to prevent the site wobbling if ($('body').outerHeight() <= $(window).height()) { $('html').css({ 'margin-right': 16 }); } // then override the { overflow-y: scroll } // in the css by setting it to a nice, safe inherit $('html').css({ 'overflow-y': 'inherit' }); elmt.sortable('enable'); } }очевидно, что это не пуленепробиваемый - если размер документа изменяется во время сортировки, то другие вещи должны быть сделаны. Однако, по моему опыту, это выглядит менее странно при таких обстоятельствах.
задание
overflow: autoзаставляет Firefox запускать перетаскивание с элементом под указателем, но также предотвращает правильную работу автопрокрутки. Вы можете увидеть это прямо в Примере сортировки jQuery, если вы сделаете окно достаточно маленьким, чтобы прокрутка была необходима.Я
overflow: scrollна теге html, но даже удаление этого и (я думаю) всех относительных содержащих элементов не полностью решило проблему (что означает, что перетаскивание начинается правильно и работает автопрокрутка). Я также попытался mozilla-нюхает патч на _findRelativeOffset (я думаю, что это было), но это не помогло.что помогло для моего случая использования было просто перетаскивание с клоном (
helper: 'clone'в перетаскиваемом конструкторе). Чтобы это выглядело так, как будто клона не было, я добавил методы start и stop, которые просто установили visibilty в hidden, а затем обратно.Я бы прокомментировал выше, но у меня пока нет очков.
была та же проблема. В моем случае не было возможности использовать "overflow:auto"-fix. Так вот что я сделал.
var pos_fixed = 1; // switch variable (the fix should only be fired ones) $('.drag').draggable({ start: function(event, ui){ pos_fixed = 0; // we're about to start, set to not fixed yet }, drag: function(event, ui){ if(pos_fixed == 0){ // check if the fix hasn't been fired for this instance yet var help_pos = $(ui.helper).offset().top, // get helpers offset targ_pos = $(event.target).offset().top, // get targets(the dragged elements) offset marg = targ_pos-help_pos; // calculate the margin the helper has to have to put it on the same y-position as our target $(ui.helper).css('margin-top', marg); // put our helper on the same y-position as the target pos_fixed = 1; // we've fixed it, we don't want it to fire again } } });исправление не заботится о том, какой браузер вы используете. Он всегда будет следить за тем, чтобы помощник имел такое же смещение y, как и цель, когда начинается перетаскивание.
для будущих читателей с этой проблемой. Я обновился с jqueryui 1.8 до 1.10.3, и проблема была решена без исправлений css.
Я также обновлен с jquery 1.8 до 1.10.2
для будущих читателей Я столкнулся с аналогичной проблемой, когда вспомогательный элемент имеет смещение при перетаскивании внутри прокрученного div диалогового окна начальной загрузки. При освобождении перетаскиваемого объекта анимация отправляет перетаскиваемый вспомогательный элемент в его новое положение без учета прокрученной части страницы, что дает запутанную обратную связь пользователям.
чтобы все работало с position: relative и overflow-y:auto в диалоговом контейнере, мое решение было
1-добавьте смещение scrollTop() к верхней части поля на вспомогательном объекте в событии начала сортировки;
2-Уберите margin-top в событии beforeStop
это исправило анимацию от выключения после перетаскивания, но вспомогательный объект нажимается ниже курсора при перетаскивании в прокрученной части страницы. Последнее исправление
3-вычислить и установить верхнее свойство вспомогательного объекта при перетаскивании (с помощью события сортировки) относительно указатель и смещение контейнера.
$(...).sortable({ ... start: function (event, ui) { ui.helper.css('margin-top', $("#mybootstrap-dialog").scrollTop()); }, beforeStop: function (event, ui){ ui.helper.css('margin-top',0); }, sort: function(event, ui) { var top = event.clientY - $('#my-sortable-ul').offset().top - $("#mybootstrap-dialog").scrollTop(); ui.helper.css({'top' : top + 'px'}); } }, ...});
помогите это помогает
суммировать ваши усилия и обеспечить завершенное решение. Следующее, Казалось, работало для Chrome 40+ и Firefox 30+
var isFirefox = /firefox/.test(navigator.userAgent.toLowerCase()); $('#target').sortable({ connectWith: '#target-holder .elements', handle: ".element-header", start: function(ev, ui) { if( isFirefox ) { ui.item.css('margin-top', $(window).scrollTop() ); } }, sort: function(ev, ui) { if( isFirefox) { ui.helper.css({'top' : ui.position.top - $(window).scrollTop() + 'px'}); } else { ui.helper.css({'top' : ui.position.top + $(window).scrollTop() + 'px'}); } }, beforeStop: function (ev, ui) { if( isFirefox ) { ui.item.css('margin-top', 0 ); } } });
мое решение: ".сортируемый", чтобы добавить "позиция: относительная"
$(".sortable").sortable({ sort: function(event, ui) { ui.position.top = ui.position.top + $(window).scrollTop(); }, });PS используется jQuery UI 1.12.0 и jQuery 2.2.4
sort: function(e, ui){ var tempVariable = $(ui.item.get(0)); tempVariable.css('top', (e.clientY)-(tempVariable.css("height").replace("px", ""))); }
Comments