向上/向下移动元素可排序列表,同时将元素保持在视口中的相同位置?

时间:2016-05-21 15:39:43

标签: javascript jquery

我有一个项目列表。格式是这样的:

||||||||||||||||||||||||||||||
|        SPACER DIV          |
||||||||||||||||||||||||||||||
|        ELEMENT DIV         |
|                            |
||||||||||||||||||||||||||||||
|        SPACER DIV          |
||||||||||||||||||||||||||||||
|        ELEMENT DIV         |
|                            |
||||||||||||||||||||||||||||||

我正在使用jQuery脚本在列表中上下移动元素:

$(sortableContainer).on('click', '.sortable-controls i', function(e){
            var that = $(e.target);
            var item = that.closest(panel);
            var thisWindow = $(window);
            var scrollTop           = thisWindow.scrollTop(),
                elementOffsetTop    = item.offset().top,
                distanceTop         = (elementOffsetTop - scrollTop);

            if(that.hasClass('sortable-up')) {

                var filler = item.prev();
                var prev = item.prevAll(panel).first();
                if (prev.length == 0)
                    return;
                item.prev().remove();

                prev.css('z-index', 999).css('position','relative').animate({
                    top: item.height() 
                }, 250);
                item.css('z-index', 1000).css('position', 'relative').animate({ top: '-' + prev.height(), queue: false}, 300, function () {
                    prev.css('z-index', '').css('top', '').css('position', '');
                    item.css('z-index', '').css('top', '').css('position', '');
                    item.insertBefore(prev);
                    filler.insertBefore(prev);
                    Abayo.builder.updateSorted(item, sortableContainer);
                });
                var scrollDifference = distanceTop - prev.height() - filler.height();

                $("html, body").animate({ scrollTop: scrollDifference, queue: false }, 300);

            } else if(that.hasClass('sortable-down')) {

                var filler = item.next();
                var next = item.nextAll(panel).first();
                if (next.length == 0)
                    return;
                item.next().remove();

                next.css('z-index', 999).css('position', 'relative').animate({ 
                    top: '-' + item.height() 
                }, 250);
                item.css('z-index', 1000).css('position', 'relative').animate({ top: next.height(), queue: false }, 300, function () {
                    next.css('z-index', '').css('top', '').css('position', '');
                    item.css('z-index', '').css('top', '').css('position', '');
                    item.insertAfter(next);
                    filler.insertAfter(next);
                    Abayo.builder.updateSorted(item, sortableContainer);
                });

                $("html, body").animate({ scrollTop: distanceTop + next.height() + filler.height(), queue: false }, 300);

            }
        })

遗憾的是,当元素不在中间并且有足够的元素来创建溢出时,这不能很好地工作。

如何更改此脚本,因为它始终将元素保留在视口中并考虑视口大小?

我必须能够一直点击顶部元素,但是点击几下后按钮就会落在我的视口之外,我必须手动滚动才能继续这个。

JSFIDDLE

2 个答案:

答案 0 :(得分:1)

如果我使用元素的偏移量,它似乎会阻止元素离开视口:

☃☃

答案 1 :(得分:0)

我发现了我做错了什么。 我首先需要计算视口的当前offsetTop是什么。

var scroll  =   thisWindow.scrollTop(),
                elementOffset   = item.offset().top,
                distance        = (elementOffset - scroll);

计算的distance只是从元素到视口的距离。 要获得当前偏移量,我只需要从distance中减去计算出的item.offset().top。然后我只需要减去/添加上一个/下一个项目高度:

元素:

$("html, body").animate({ scrollTop:  elementOffset - distance - prev.height(), queue: false }, 300);

元素向下:

$("html, body").animate({ scrollTop:  elementOffset - distance + next.height(), queue: false }, 300);

JsFiddle