jQuery UI 可排序滚动辅助元素偏移 Firefox 问题

Posted

技术标签:

【中文标题】jQuery UI 可排序滚动辅助元素偏移 Firefox 问题【英文标题】:jQuery UI sortable scroll helper element offset Firefox issue 【发布时间】:2011-01-27 22:26:41 【问题描述】:

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

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

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

【问题讨论】:

这是一个演示该错误的 gif(引用自已接受答案中的 jQuery 论坛帖子):i.imgur.com/phYGO.gif 【参考方案1】:

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

【讨论】:

这是使用 JQuery-UI 可拖动和可放置的唯一对我有用的答案。 这在所有浏览器上都非常适合我,当然是最简单/最干净的解决方案。干杯! 绝对是最干净的解决方案。无法定义容器 position:relative 是一个非常严重的限制 这对我有用,而 position:relative 没有,谢谢。 position: static;overflow: auto; 的组合为我做到了【参考方案2】:

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

【讨论】:

天哪,这是一个很棒的解决方案!我喜欢这个,因为它不测试用户代理,也不需要可能破坏其他网站页面布局的更改。 终于有一个有效的修复程序!非常感谢你。你已经在我家中赢得了三代人的青睐。 最后,它也适用于 jQuery UI 1.11.4,谢谢! 这解决了问题,但使containment 选项无用。 您先生是这个解决方案的英雄。谢谢。【参考方案3】:

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

【讨论】:

为我工作,但由于其他原因,我无法删除职位:相对。相反,@rtcherry 的解决方案适用于我:***.com/a/20225012/72350【参考方案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');
    
);

我发现,如果您使用可排序元素滚动,仍然会出现问题。也许有人对此有解决方案?

更新: 解决方法是:

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

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

【讨论】:

这对我来说是溢出:自动对我来说不是一个选项。【参考方案5】:

您还需要考虑到这是特定于 firefox 的事实,这是我正在使用的 sn-p - 我从 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 次不同的调用。

【讨论】:

太好了,你在这里为我省了很多麻烦。 这对我来说是一个很好的解决方案,因为我使用的是 jquery 1.4.2 和 jquery-ui.1.8.23,所以我遇到了这个问题,所以现在它会解决。使用 jquery.1.8.js 也可以解决此问题,但是当我将 jquery.1.4.2 替换为 jquery.1.8.js 时遇到了很多问题,所以 thnx 不得不这样做让我感到恶心,但这是唯一有效的解决方案(类似于 50235289)。不过,说真的,我的胃病了。叹息。 实际上通过删除我的 CSS 中的 html overflow-x: hidden; 解决了这个问题。不真实。【参考方案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'
);

基本上,你需要监听 sortable 的 "start" 事件,将浏览器当前的 scrollTop() 值添加到 helper 的位置,然后你需要监听 sortable 的 "beforeStop" 事件,在项目被正式放回列表中的新位置。

希望对某人有所帮助!

【讨论】:

【参考方案7】:

我在我的网站上强制使用滚动条,因此由于我的 CSS 中有 html overflow-y: scroll 而出现了这个可滚动偏移问题。

当我打开和关闭可滚动时,我使用以下方法来解决它。我只在 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 UI 版本“修复”了这个问题。

jQuery 1.8.0 jQuery UI 1.8.23

【讨论】:

我正在使用 jquery 1.8.2 和 jquery ui 1.9,但仍然无法使用【参考方案9】:

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

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

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

2- 移除 beforeStop 事件中的 margin-top

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

3- 在拖动(使用排序事件)时计算并设置辅助对象的 top 属性,相对于指针和容器偏移量。

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

);

帮帮忙

【讨论】:

【参考方案10】:

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

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

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

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

【讨论】:

【参考方案11】:

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

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

【讨论】:

【参考方案12】:

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

http://jqueryui.com/

我也从 jquery 1.8 升级到 1.10.2

http://jquery.com/

【讨论】:

【参考方案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”添加“位置:相对”

$(".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", "")));
    

【讨论】:

以上是关于jQuery UI 可排序滚动辅助元素偏移 Firefox 问题的主要内容,如果未能解决你的问题,请参考以下文章

jQuery UI,可拖动,可放置,自动滚动

jQuery ui 可拖动元素在滚动 div 之外不能“拖动”

滚动浏览器时使用错误起始位置的可拖动 jQuery UI 元素?

Jquery ui - 可排序:在可排序元素中按图标“句柄”拖动

jQuery UI 可拖动元素放入可排序

滚动后可拖动的jQuery UI不粘在网格上