1

垂直方向にスクロールするコンテナ内にjquery sortablesがいくつかあります。これらのコンテナ間でドラッグすると、コンテナの下にドラッグすることでアイテムをソート可能に追加できます。次の html を検討してください。

    <style>
        .constrainer {
            height: 160px;
            overflow-y: auto;
            width:280px;
            border: 1px solid orange;
        }
        .sortitem {
            border: 1px solid #807eba;
            width: 160px
            display:inline-block;
            padding: 10px;
            margin: 10px;
            background-color: white;
        }
    </style>

    <div class="constrainer" style="float:left">
        <ul class="sortme">
            <li class="sortitem">item 1</li>
            <li class="sortitem">item 2</li>
            <li class="sortitem">item 3</li>
            <li class="sortitem">item 4</li>
            <li class="sortitem">item 5</li>
            <li class="sortitem">item 6</li>
        </ul>
    </div>
    <div class="constrainer" style="float:right">
        <ul class="sortme">
            <li class="sortitem">item 1</li>
            <li class="sortitem">item 2</li>
            <li class="sortitem">item 3</li>
            <li class="sortitem">item 4</li>
            <li class="sortitem">item 5</li>
            <li class="sortitem">item 6</li>
        </ul>
    </div>

そして、次のスクリプト:

$('.sortme').sortable({connectWith: '.sortme'});

リストの下を押すと、リストの 1 つから別のリストに項目を簡単にドラッグできることに注意してください。

途切れたリストへのドラッグを防止したい。私の実際のアプリケーションでは、はるかに複雑な DOM 構造があるため、実際のソリューションでは、ビュー内にあるソート可能な実際の領域を見つけ、その領域にのみドロップできるようにする必要があります。単一のソート可能なアイテムの並べ替えについても同じです。

上記のコードの jsfiddle は次のとおりです: http://jsfiddle.net/PFSsJ/

編集:明確化

明確にするために、非表示のリストの部分ではなく、表示されているリストの部分に項目をドラッグしたいと考えています。さらに楽しくするには、リストを垂直に配置して、jquery ui がドロップするリストを決定できず、次のように前後にちらつきます: http://jsfiddle.net/PFSsJ/1/

4

1 に答える 1

0

この問題のさまざまな解決策に約 2 週間を費やしました。以下のコードは、私が構築しているアプリケーションで機能しています。垂直方向に積み重ねられ、垂直方向にスクロールするソータブルのみを扱うことに注意してください。水平方向のソート可能オブジェクトを処理するように変更できる可能性がありますが、私のユースケースに合わないため、試していません。

$('.ulClass').boundedSortable(); と同じように使用します。

(function($) {
$.widget("ui.boundedSortable", $.ui.sortable, {
    widgetEventPrefix: "sort",
    _init: function () {
        this.element.data("sortable", this.element.data("boundedSortable"));
        return $.ui.sortable.prototype._init.apply(this, arguments);
    },
    _create:function() {
        var ret = $.ui.sortable.prototype._create.apply(this, arguments);
        this.containerCache.sortable = this;
        return ret;
    },
    refreshPositions:function(fast){
        $.ui.sortable.prototype.refreshPositions.apply(this, arguments);
        _.each(this.items, function(item){
            var element = item.item[0];
            var offset = item.item.offset();
            var points = [[offset.left + 1, offset.top + 1],
                          [offset.left + (item.width / 2), offset.top + (item.height / 2)],
                          [offset.left + item.width - 1, offset.top + 1],
                          [offset.left + item.width - 1, offset.top + item.height - 1]];
            item.visible = _.any(points, function(point){
                var visibleElement = $.elementFromPoint(point[0], point[1]);
                if(element === visibleElement || (visibleElement && $.contains(element, visibleElement))){
                    return true;
                }
                return false;
            });
        }, this);

        _.each(this.containers, function(container){
            var parent = container.element;
            var cache = container.containerCache;
            while((parent = parent.parent()) && parent.length){
                parent = $(parent);
                var offset = parent.offset();
                var parentHeight = parent.height();
                if(cache.height > parentHeight){
                    cache.height = Math.round(parentHeight);
                }
                if(offset && cache.top < offset.top){
                    cache.top = offset.top;
                }
            }
        }, this);
        return this;
    },
    _intersectsWithPointer: function (item) {
        var ret = $.ui.sortable.prototype._intersectsWithPointer.apply(this, arguments);
        if(ret){
            if(!item.visible){
                return false;
            }
        }
        return ret;
    },
    _clear: function(){
        if(!(this.placeholder && this.placeholder[0].parentNode)){
            this.placeholder = [{parentNode:{removeChild:function(){}}}];
            this.placeholder.before = function(){};
        }
        return $.ui.sortable.prototype._clear.apply(this, arguments);
    },
    _contactContainers: function(event) {

        /** directly from jQuery source **/

        // get innermost container that intersects with item
        var innermostContainer = null, innermostIndex = null;


        for (var i = this.containers.length - 1; i >= 0; i--){

            // never consider a container that's located within the item itself
            if($.ui.contains(this.currentItem[0], this.containers[i].element[0])){
                continue;
            }
            if(this._intersectsWith(this.containers[i].containerCache)) {

                // if we've already found a container and it's more "inner" than this, then continue
                if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0])){
                    continue;
                }
                innermostContainer = this.containers[i];
                innermostIndex = i;

            } else {
                // container doesn't intersect. trigger "out" event if necessary
                if(this.containers[i].containerCache.over) {
                    this.containers[i]._trigger("out", event, this._uiHash(this));
                    this.containers[i].containerCache.over = 0;
                }
            }

        }

        /** end direct copy from jQuery source*/

        if(!innermostContainer){
            if (this.placeholder) {
                if(this.placeholder[0].parentNode) {
                    this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
                }
            }
            this.currentContainer = null;
            return;
        }
        return $.ui.sortable.prototype._contactContainers.apply(this, arguments);
    }
});
})(jQuery);

(function ($){
    var check=false, isRelative=true;
    $.elementFromPoint = function(x,y)
    {
        var elemFromPtFunc = null;
        if(document.getElementFromPoint){
            elemFromPtFunc = _.bind(document.getElementFromPoint, document);
        }else if(document.elementFromPoint){
            elemFromPtFunc = _.bind(document.elementFromPoint, document);
        }

        if(!elemFromPtFunc) {
            console.error('no element from point?');
            return null;
        }
        var scrollTop = $(document).scrollTop();
        var scrollLeft = $(document).scrollLeft();
        return elemFromPtFunc(x - scrollLeft,y - scrollTop);
    };
})(jQuery);
于 2012-10-25T15:56:35.397 に答える