应用CSS3比例时,Sortable行为错误

时间:2014-07-26 12:00:49

标签: jquery css3 jquery-ui jquery-ui-sortable

我正在使用CSS转换扩展JQuery可排序元素。两个可排序的项目开始位置和偏移,而拖动是错误的,因为JQuery不考虑CSS标度。我用这里的代码部分解决了它:

jQuery Drag/Resize with CSS Transform Scale

但我无法解决的问题是拖动开始时的可排序项目位置。它向上跳了一下。我无法弄清楚要放入启动事件处理程序的内容:

        start: function(e, ui)
        {
            // something is needed here to fix the initial offset
        }

这个小提琴显示了问题: http://jsfiddle.net/adrianrosca/zbvLp/4/

2 个答案:

答案 0 :(得分:8)

可拖动的一个区别是转换不在元素本身上,而是在父元素上。所以它改变了一点逻辑。

这是针对此特定情况的解决方案,但您会发现根据情况可能会发生变化。例如,如果您更改 transform-origin ,或者您有水平排序,则必须对其进行调整。但逻辑保持不变:

var zoomScale = 0.5;

$(".container")
  .sortable({

    sort: function(e, ui) {
    console.log(ui.position.left)
      var changeLeft = ui.position.left - ui.originalPosition.left;
      // For left position, the problem here is not only the scaling,
      // but the transform origin. Since the position is dynamic
      // the left coordinate you get from ui.position is not the one
      // used by transform origin. You need to adjust so that
      // it stays "0", this way the transform will replace it properly
      var newLeft = ui.originalPosition.left + changeLeft / zoomScale - ui.item.parent().offset().left;

      // For top, it's simpler. Since origin is top, 
      // no need to adjust the offset. Simply undo the correction
      // on the position that transform is doing so that
      // it stays with the mouse position
      var newTop = ui.position.top / zoomScale;

      ui.helper.css({
        left: newLeft,
        top: newTop
      });
    }
  });

http://jsfiddle.net/aL4ntzsh/5/

编辑:

以前的答案将适用于定位,但正如Decent Dabbler指出的那样,交叉函数存在一个缺陷,可以在进行排序时进行验证。基本上,位置是正确计算的,但项目保持宽度高度未转换的值,这会导致问题。 您可以通过在开始事件上修改这些值来调整这些值,以考虑比例因子。像这样举例如:

 start: function(e, ui) {
      var items = $(this).data()['ui-sortable'].items;
      items.forEach(function(item) {
        item.height *= zoomScale;
        item.width *= zoomScale;
      });
    }

http://jsfiddle.net/rgxnup4v/2/

答案 1 :(得分:1)

你的问题有两件事:

  1. 元素的位置属性是基于最近的父级计算的,该父级的位置是绝对的或相对的。现在基于父母的身体是不好的,所以你必须为容器添加position:relative;
  2. 因为,正如您已经注意到的那样,在计算ui.positionui.originalPosition时,JQuery不会考虑CSS比例,因此您必须"应用" zoomScale他们两个。
  3. CSS

    .container
    {
        position: relative;
        transform: scale(0.5);
        transform-origin: center top;
    }
    

    脚本

    var changeLeft = ui.position.left - ui.originalPosition.left;
    var newLeft = (ui.originalPosition.left + changeLeft) / zoomScale;
    var changeTop = ui.position.top - ui.originalPosition.top;
    var newTop = (ui.originalPosition.top + changeTop) / zoomScale;
    

    这是更新代码:http://jsfiddle.net/zbvLp/9/