【问题标题】:jQuery UI sortable scroll helper element offset Firefox issuejQuery UI 可排序滚动辅助元素偏移 Firefox 问题
【发布时间】: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

标签: jquery firefox scroll offset jquery-ui-sortable


【解决方案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

【讨论】:

【解决方案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", "")));
                      }
                  

                  【讨论】:

                    猜你喜欢
                    • 2017-11-13
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-06-24
                    • 2014-07-02
                    • 2011-11-08
                    • 2012-09-19
                    • 1970-01-01
                    • 2014-05-12
                    相关资源
                    最近更新 更多