Подтвердить что ты не робот

JQuery UI sortable scroll вспомогательный элемент смещения Firefox issue

У меня проблема с списком сортировки jQuery UI 1.7.2 в Firefox 3.6, IE7-8 работает нормально. Когда я немного прокручивается, хелпер-элемент, похоже, имеет смещение той же высоты, что и я прокручивается вниз от указателя мыши, из-за чего невозможно увидеть, какой элемент вы первоначально начали перетаскивать. Как исправить это или решить проблему? Если нет никакого исправления, что является действительно хорошим альтернативным плавным плагином?

Вот мои параметры инициализации для сортируемых.

$("#sortable").sortable( {placeholder: 'ui-state-highlight'  } );
$("#sortable").disableSelection();
4b9b3361

Ответ 2

Если вы хотите предотвратить обнюхивание браузером, единственным решением CSS является установка стиля ul или контейнера overflow: auto. Если вы посмотрите на источник через firebug, это способ, которым jQuery делает это в своем примере.

Ответ 3

Использование 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.

Изменить. Это использование jQuery 1.10.0 и jQuery UI 1.10.3.

Ответ 4

У меня также была эта проблема и исправлена ​​ее с помощью следующего кода:

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'});
    }
});

Я обнаружил, что все еще есть проблема, если вы прокручиваете свой сортируемый элемент. Может быть, у кого-то есть решение для этого?

UPDATE: Исправление:

$sortable_elements.sortable({ 
    connectWith: '#personal-favs ul.fitems',
    sort: function(event, ui) {  
        ui.helper.css({'top' : ui.position.top + $(window).scrollTop() + 'px'});
    }
});

Но все же - если вы покидаете список, событие сортировки, похоже, останавливается.

Ответ 5

Вам также нужно учитывать тот факт, что это специфично для firefox, вот фрагмент, который я использую - я получил правильное решение от решения Harris. Я столкнулся с этой проблемой без использования хелпера, когда сортируемая была в относительно позиционированном контейнере.

  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 разных вызова в зависимости от браузера.

Ответ 6

Мне удалось найти исправление для этого:

$( "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", чтобы удалить это смещение перед элемент официально помещен в список на новом месте.

Надеюсь, что это поможет кому-то!

Ответ 7

Я заставляю полосы прокрутки на моем сайте, поэтому эта проблема с прокручиваемым смещением возникает из-за наличия 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');
    }
  }

Очевидно, что это не пуленепробиваемый - если размер документа изменяется при сортировке, тогда придется делать другие вещи. Однако, по моему опыту, в этих условиях он выглядит менее странным.

Ответ 8

Я "исправил" это, используя новые версии пользовательского интерфейса jQuery/jQuery.

  • jQuery 1.8.0
  • jQuery UI 1.8.23

Ответ 9

Настройка overflow: auto заставляет Firefox начинать перетаскивание с помощью элемента под указателем, но также препятствует правильной работе autoscroll. Вы можете увидеть это прямо в примере сортировки jQuery, если вы сделаете окно достаточно маленьким, чтобы прокрутка была необходима.

У меня был overflow: scroll в теге html, но даже удаление этого и (я думаю) всех элементов, содержащих относительные элементы, не полностью решает проблему (это означает, что перетаскивание начинается правильно, а автосканирование работает). Я также попробовал патч для мозаики, который был для _findRelativeOffset (я думаю, что это было), но это не помогло.

Что помогло для моего использования, было просто перетаскивание с помощью клона (helper: 'clone' в конструкторе draggable). Чтобы сделать его похожим на то, что клона не было, я добавил методы запуска и остановки, которые просто устанавливают видимость в скрытую, а затем обратно.

Я бы прокомментировал выше, но у меня еще нет очков.

Ответ 10

Была та же проблема. В моем случае не удалось использовать "переполнение: авто" -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-offset, что и цель, когда начинается перетаскивание.

Ответ 11

Для будущих читателей с этой проблемой. Я обновился с jqueryui 1.8 до 1.10.3, и проблема была решена без исправлений css.

http://jqueryui.com/

Я также обновил с jquery 1.8 до 1.10.2

http://jquery.com/

Ответ 12

Для будущих читателей Я столкнулся с аналогичной проблемой, когда вспомогательный элемент имеет смещение при перетаскивании внутри прокрученного div окна бутстрапа. При отпускании перетаскиваемого объекта анимация отправляет перетаскиваемый вспомогательный элемент к новой позиции без учета прокрученной части страницы, что дает пользователям путаную обратную связь.

Чтобы сохранить работу с позицией: relative и overflow-y: auto в контейнере диалога, мое решение было

1- Добавьте смещение scrollTop() в margin-top на вспомогательном объекте в событии запуска сортировки;

2- удалите верхний край в событии 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'});
    }
},
...

});

Помогите, это поможет

Ответ 13

Подводя итог вашим усилиям и предоставив законченное решение. Казалось, что для 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 );
        }
    }
});

Ответ 14

Мое решение: ".sortable" добавить "position: relative"

$(".sortable").sortable({
      sort: function(event, ui) {
           ui.position.top = ui.position.top + $(window).scrollTop();
      },
});

PS используется jQuery UI 1.12.0 и jQuery 2.2.4

Ответ 15

sort: function(e, ui){
        var tempVariable = $(ui.item.get(0));
        tempVariable.css('top', (e.clientY)-(tempVariable.css("height").replace("px", "")));
    }