使用jquery-sortable无法将大项目拖动到最顶层/最底层

时间:2015-06-02 14:14:48

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

将大型商品拖到最顶层或最底层位置时会出现问题。

演示:http://jsfiddle.net/vladimir_ze/b2Q9b/17/

在排序之前(在start事件上)我减少元素大小以使大型元素的排序变得容易,但似乎计算仍然使用元素原始高度(在我将其设置为较小的大小之前)。

任何想法如何解决?

已更新

我最近在搜索start事件之前是否可以更改元素高度时遇到了一个有趣的链接(jQuery UI : Before start draggable),结果发现可以使用beforeStart事件扩展sortable。

var oldMouseStart = $.ui.sortable.prototype._mouseStart;
$.ui.sortable.prototype._mouseStart = function (event, overrideHandle, noActivation) {
    this._trigger('beforeStart', event, this._uiHash());
    oldMouseStart.apply(this, [event, overrideHandle, noActivation]);
};

beforeStart触发时,我会应用课程以最小化该项目并拨打.sortable('refresh')

结果如下:http://jsfiddle.net/vladimir_ze/b2Q9b/18/ 它仍然有点马车,但如果你从顶部边缘开始拖动它会很好。

1 个答案:

答案 0 :(得分:4)

这似乎是jquery中的一个错误,它已经是logged

修复它将在1.12版本中提供。 同时,您可以按照this link.Working fiddle中的建议将以下代码添加到您的脚本中。

$.widget("ui.sortable", $.extend({}, $.ui.sortable.prototype, {
_mouseDrag: function(event) {
    var i, item, itemElement, intersection,
        o = this.options,
        scrolled = false,
        touchingEdge;

    //Compute the helpers position
    this.position = this._generatePosition(event);
    this.positionAbs = this._convertPositionTo("absolute");

    if (!this.lastPositionAbs) {
        this.lastPositionAbs = this.positionAbs;
    }

    //Do scrolling
    if(this.options.scroll) {
        if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {

            if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
                this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
            } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
                this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
            }

            if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
                this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
            } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
                this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
            }

        } else {

            if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
                scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
            } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
                scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
            }

            if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
                scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
            } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
                scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
            }

        }

        if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
            $.ui.ddmanager.prepareOffsets(this, event);
        }
    }

    //Regenerate the absolute position used for position checks
    this.positionAbs = this._convertPositionTo("absolute");

    //Set the helper position
    if(!this.options.axis || this.options.axis !== "y") {
        this.helper[0].style.left = this.position.left+"px";
    }
    if(!this.options.axis || this.options.axis !== "x") {
        this.helper[0].style.top = this.position.top+"px";
    }

    // Check if the helper is touching the edges of the containment.
    if(this.containment) {
        if((this.positionAbs.left === this.containment[0] || this.options.axis === "y") &&
                (this.positionAbs.top === this.containment[1] || this.options.axis === "x")) {
            touchingEdge = 0;
            this.direction = "down";
        }
        else if((this.positionAbs.left === this.containment[2] || this.options.axis === "y") &&
                (this.positionAbs.top === this.containment[3] || this.options.axis === "x")) {
            touchingEdge = this.items.length - 1;
            this.direction = "up";
        }
    }

    if(touchingEdge !== undefined && this.helper[0] !== this.items[touchingEdge].item[0]) {
        // Rearrange, if the helper is touching the edge of the containment and not
        // already the item at the edge.
        this._rearrange(event, this.items[touchingEdge], false);
        this._trigger("change", event, this._uiHash());
    } else {
        //Rearrange
        for (i = this.items.length - 1; i >= 0; i--) {

            //Cache variables and intersection, continue if no intersection
            item = this.items[i];
            itemElement = item.item[0];
            intersection = this._intersectsWithPointer(item);
            if (!intersection) {
                continue;
            }

            // Only put the placeholder inside the current Container, skip all
            // items from other containers. This works because when moving
            // an item from one container to another the
            // currentContainer is switched before the placeholder is moved.
            //
            // Without this, moving items in "sub-sortables" can cause
            // the placeholder to jitter beetween the outer and inner container.
            if (item.instance !== this.currentContainer) {
                continue;
            }

            // cannot intersect with itself
            // no useless actions that have been done before
            // no action if the item moved is the parent of the item checked
            if (itemElement !== this.currentItem[0] &&
                this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
                !$.contains(this.placeholder[0], itemElement) &&
                (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
            ) {
                this.direction = intersection === 1 ? "down" : "up";

                if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
                    this._rearrange(event, item);
                } else {
                    break;
                }

                this._trigger("change", event, this._uiHash());
                break;
            }
        }
    }

    //Post events to containers
    this._contactContainers(event);

    //Interconnect with droppables
    if($.ui.ddmanager) {
        $.ui.ddmanager.drag(this, event);
    }

    //Call callbacks
    this._trigger("sort", event, this._uiHash());

    this.lastPositionAbs = this.positionAbs;
    return false;

}
}));
相关问题