56

我在 Firefox 3.6 中的 jQuery UI 1.7.2 可排序列表有问题,IE7-8 工作正常。当我向下滚动一点时,辅助元素的偏移量似乎与我从鼠标指针向下滚动的高度相同,这使得无法看到您最初开始拖动的项目。如何解决此问题或解决此问题?如果没有修复什么是真正好的替代可拖动插件?

这是我的可排序的初始化参数。

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

15 回答 15

132

如果要防止浏览器嗅探,CSS 唯一的解决方案是将 ul 或容器样式设置为overflow: auto. 如果您通过 firebug 查看源代码,那么 jQuery 在他们的示例中就是这样做的。

于 2010-08-03T02:48:38.207 回答
48

使用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。

于 2013-11-26T18:26:05.713 回答
25

我看到了这个问题,并且能够通过从我的页面上的一个包含 div 中删除 css 规则 position:relative 来解决它。另请参阅:http: //forum.jquery.com/topic/sortable-offset-when-element-is-dragged-and-page-scrolled-down-ff

于 2010-08-16T20:49:23.247 回答
20

我也遇到了这个问题,用下面的代码解决了这个问题:

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

但是仍然 - 如果您要离开列表,排序事件似乎会停止。

于 2011-04-04T08:00:43.280 回答
9

您还需要考虑到这是特定于 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 次不同的调用。

于 2010-06-06T04:28:05.587 回答
7

我设法解决了这个问题:

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

基本上,您需要监听 sortable 的“start”事件以将浏览器的当前 scrollTop() 值添加到 helper 的位置,然后您需要监听 sortable 的“beforeStop”事件,以在项目正式发布之前删除该偏移量放回列表中的新位置。

希望这对某人有帮助!

于 2010-05-15T17:59:52.293 回答
4

我在我的网站上强制使用滚动条,所以由于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');
    }
  }

显然,这不是万无一失的——如果文档大小在排序时发生变化,则必须做其他事情。但是,根据我的经验,在这种情况下它看起来不那么奇怪。

于 2012-05-29T21:10:23.370 回答
1

我使用较新的 jQuery/jQuery UI 版本“修复”了这个问题。

  • jQuery 1.8.0
  • jQuery UI 1.8.23
于 2012-08-28T09:41:44.073 回答
1

对于未来的读者,我遇到了类似的问题,即在引导对话框的滚动 div 内拖动时,辅助元素有偏移。当释放拖动的对象时,动画将拖动的辅助元素发送到它的新位置,而不考虑页面的滚动部分,这给用户带来了令人困惑的反馈。

为了让事情在对话容器中使用 position:relative 和 overflow-y:auto ,我的解决方案是

1- 在排序开始事件中将 scrollTop() 偏移量添加到辅助对象的边距顶部;

2-在 beforeStop 事件中删除 margin-top

这修复了拖动后动画关闭的问题,但是在页面中的滚动部分拖动时,辅助对象被推到光标下方。最后的修复是

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

});

帮助这有帮助

于 2015-02-10T20:15:04.983 回答
0

设置overflow: auto使 Firefox 开始拖动指针下的元素,但它也会阻止自动滚动正常工作。您可以在 jQuery Sortable 示例中看到这一点,如果您使窗口足够小以至于需要滚动。

我有overflow: scrollhtml 标签,但即使删除它和(我认为)所有相关的包含元素并不能完全解决问题(意味着拖动正确开始并且自动滚动有效)。我还尝试了 _findRelativeOffset 的 mozilla 嗅探补丁(我认为就是这样),但它没有帮助。

对我的用例有帮助的只是用克隆拖动(helper: 'clone'在可拖动的构造函数中)。为了让它看起来克隆不存在,我添加了 start 和 stop 方法,只是将可见性设置为隐藏然后返回。

我会在上面发表评论,但我还没有要点。

于 2012-03-02T12:49:04.413 回答
0

有同样的问题。在我的情况下,不可能使用“溢出:自动”修复。所以这就是我所做的。

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 偏移量。

于 2013-07-09T08:21:46.397 回答
0

对于有这个问题的未来读者。我从 jqueryui 1.8 升级到 1.10.3 并且没有修复 css 问题就解决了。

http://jqueryui.com/

我也从 jquery 1.8 升级到 1.10.2

http://jquery.com/

于 2013-09-16T15:50:33.710 回答
0

总结您的努力并提供完整的解决方案。以下似乎适用于 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 );
        }
    }
});
于 2015-03-10T12:53:49.063 回答
-1

我的解决方案:“.sortable”添加“位置:相对”

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

PS 使用 jQuery UI 1.12.0 和 jQuery 2.2.4

于 2016-08-25T10:56:22.290 回答
-2

sort: function(e, ui){
        var tempVariable = $(ui.item.get(0));
        tempVariable.css('top', (e.clientY)-(tempVariable.css("height").replace("px", "")));
    }
于 2015-06-03T09:48:30.563 回答