如何通过绝对定位获得 jQuery UI 可排序工作?

发布于 2024-12-01 22:50:04 字数 511 浏览 0 评论 0原文

我正在尝试使用 jQuery UI 可排序 (http://jqueryui.com/demos/sortable/ )在页面上拖放排序几个 DOM 元素。所有元素都有绝对定位,这就是问题开始的地方。 jQuery UI 似乎认为所有 li 都放置在左上角(无论如何,这就是占位符结束的位置)。

我在这里创建了一个jsfiddle: http://jsfiddle.net/winter/4ePe6/ 问题所在相当亲力亲为。

我想要实现的目标如下:当项目 1 放在项目 2 和项目 3 之间时,项目 2 会移动到项目 1 所在的位置,项目 1 占据项目 2:s 的位置,项目 3 及以上的位置保持在原来的位置。放置前占位符显示放置时项目 1 的放置位置,即项目 2 的实际移动发生在放置之前。

提前致谢。

I'm trying to use jQuery UI sortable (http://jqueryui.com/demos/sortable/) on a page to drag'n'drop sort a couple of DOM elements. All elements have absolute positioning and this is where the problems start. It seems that jQuery UI thinks that all of the li's are placed in the top left corner (that's where the placeholder ends up anyway).

I created a jsfiddle here: http://jsfiddle.net/winter/4ePe6/ where the problem is quite hands on.

What I want to achieve is the following: When item 1 is dropped between item 2 and 3, item 2 is moved to where item 1 was, item 1 takes item 2:s place and item 3 and up stays where they are. Before dropping the placeholder shows where item 1 will be placed when dropped, i.e. the actual moving of item 2 occurs before the dropping.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

少年亿悲伤 2024-12-08 22:50:04

jQuery UI 可能会做出一些假设,但占位符的具体问题在于其样式设置为相对定位而不是绝对定位。由于没有其他相对定位的元素,占位符最终位于起始位置。

要将占位符定位在移动元素所在的位置,您需要执行两件事:

  1. 为占位符提供自己的类,并
  2. 根据占位符所代表的元素设置占位符的位置。

例如它的类和样式:

.my-placeholder {
  background:red;
  height: 1.5em;
  line-height: 1.2em;
  position: absolute;
  top: 20%;
  width: 10%;
}

现在剩下的就是根据它要替换的元素设置它的“左”位置。这是通过设置“start”事件处理程序在拖动开始时执行此操作来完成的。

$("#sortable").sortable({
    placeholder: "my-placeholder",
    start: function(event, ui) {
        $(".my-placeholder").css("left", ui.originalPosition.left);
    },
});

jQuery UI might be making some assumptions, but the problem specifically with the placeholder is that its style is set for relative rather than absolute positioning. As there are no other relatively positioned elements, the placeholder ends up at the starting position.

To position the placeholder over where the moving element is, you need to do two things:

  1. Give the placeholder its own class and
  2. Set the placeholder’s position depending on the element that it’s standing in for.

For example for its class and style:

.my-placeholder {
  background:red;
  height: 1.5em;
  line-height: 1.2em;
  position: absolute;
  top: 20%;
  width: 10%;
}

Now all that remains is to set its “left” position according to the element that it is replacing. This is done by setting the “start” event handler to do that when the drag begins.

$("#sortable").sortable({
    placeholder: "my-placeholder",
    start: function(event, ui) {
        $(".my-placeholder").css("left", ui.originalPosition.left);
    },
});
默嘫て 2024-12-08 22:50:04

通过跳过绝对位置并通过 li 之间的填充和 ul 周围的绝对定位 div 包装器来解决这个问题。

Solved this by skipping the absolute placements and worked it out with padding between the li's and an absolute positioned div-wrapper around the ul.

始终不够 2024-12-08 22:50:04

我可以让它工作...
但必须在拖动时将 $window.scrollTop() 添加到项目中...

$tracksSortable = $tracks
    .sortable('destroy')
    .disableSelection()
    .sortable({
        update:function(){
        },
        sort: function(event, ui) {
            $(ui.item).css({marginTop:$window.scrollTop()+'px'});
        },
        beforeStop: function(event, ui) {
            $(ui.item).css({marginTop:'0'});
        },
        items         : '.track',
        axis          : 'y',
        scroll        : true,
        containment   : 'body',
        placeholder   : 'trackPlaceHolder',
        distance      : 10,
        delay         : 500,
        revert        : false,
        cursorAt      : {top:15}
    });

I CAN get it work...
But have to add $window.scrollTop() to item while dragging...

$tracksSortable = $tracks
    .sortable('destroy')
    .disableSelection()
    .sortable({
        update:function(){
        },
        sort: function(event, ui) {
            $(ui.item).css({marginTop:$window.scrollTop()+'px'});
        },
        beforeStop: function(event, ui) {
            $(ui.item).css({marginTop:'0'});
        },
        items         : '.track',
        axis          : 'y',
        scroll        : true,
        containment   : 'body',
        placeholder   : 'trackPlaceHolder',
        distance      : 10,
        delay         : 500,
        revert        : false,
        cursorAt      : {top:15}
    });
陌生 2024-12-08 22:50:04

有两种方法可以实现这一目标。您可以通过 nth-childnth-type-of 选择器使用一些 CSS 技巧,将绝对定位应用于索引而不是直接应用于元素。因此,当项目由于可排序插件的工作方式而在 DOM 树中移动时,它们将捕获正确的位置属性,因为索引将保持不变。

另一种方法是使用插件的 sortchange 事件,只要列表中项目的顺序发生更改,该事件就会触发。因此,在事件函数中,您需要迭代您的项目并重新应用正确的定位。

请参阅此博文,了解有关如何使用这两种方法:

There are 2 ways you can achieve this. You can use some CSS trickery with the nth-child or nth-type-of selector to apply your absolute positioning to indices rather than directly to elements. Thus, when items shift around in the DOM tree due to how the sortable plugin works, they'll capture the correct position attributes since the indices will stay the same.

The other way is using the sortchange event of the plugin which fires whenever the order of the items in your list is changed. Thus, in the event function, you need to iterate through your items and re-apply the correct positioning.

See this blogpost for more details on how to use both methods:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文