gpt4 book ai didi

javascript - 如何防止落入 jquery 可排序的不可见部分

转载 作者:行者123 更新时间:2023-11-28 09:38:17 26 4
gpt4 key购买 nike

我在垂直滚动的容器内有几个 jquery 可排序对象。在这些容器之间拖动时,可以通过在容器下方拖动来将项目添加到可排序中。考虑以下 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'});

请注意,您可以通过点击列表下方轻松将项目从一个列表拖动到另一个列表。

我想防止拖动到被切断的列表。在我的实际应用程序中,有一个更复杂的 DOM 结构,因此实际的解决方案需要找到 View 中可排序的实际区域,并仅允许在该区域中放置。与在单个可排序中重新排序项目相同。

这是上面代码的 jsfiddle: http://jsfiddle.net/PFSsJ/

编辑:澄清

需要明确的是,我仍然想将项目拖动到列表中可见的部分,而不是列表中不可见的部分。为了更有趣,垂直排列列表,这样 jquery ui 就无法决定将其放在哪一个上,并且它会像这样来回闪烁:http://jsfiddle.net/PFSsJ/1/

最佳答案

我花了大约两周的时间研究这个问题的各种解决方案。下面的代码在我正在构建的应用程序中为我工作。请注意,它仅处理垂直堆叠和垂直滚动的可排序对象。它可能会被修改以处理水平排序,但我没有尝试过,因为它不适合我的用例。

你使用它就像一个可排序的,只需 $('.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);

关于javascript - 如何防止落入 jquery 可排序的不可见部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12718304/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com