Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JQuery Draggable-防止网格对象位于同一位置_Javascript_Jquery_Jquery Ui_Jquery Draggable - Fatal编程技术网

Javascript JQuery Draggable-防止网格对象位于同一位置

Javascript JQuery Draggable-防止网格对象位于同一位置,javascript,jquery,jquery-ui,jquery-draggable,Javascript,Jquery,Jquery Ui,Jquery Draggable,我使用jquerydraggable在网格上移动项目。对象捕捉到32x32栅格区域。如果对象处于相同位置,我希望能够取消栅格捕捉 不能取消拖动,只能阻止它进入正方形。阻止并移回前一位置后,如果用户继续拖动到新的未占用网格位置,则必须捕捉到该位置 我已经创建了一个演示,用于上面解释的目的,但是当它试图进入新位置时,图像会出现小故障,但随后被取消回到旧位置 这是小提琴中的代码: <div class="drop-target"> <div class="dr

我使用jquerydraggable在网格上移动项目。对象捕捉到32x32栅格区域。如果对象处于相同位置,我希望能够取消栅格捕捉

不能取消拖动,只能阻止它进入正方形。阻止并移回前一位置后,如果用户继续拖动到新的未占用网格位置,则必须捕捉到该位置

我已经创建了一个演示,用于上面解释的目的,但是当它试图进入新位置时,图像会出现小故障,但随后被取消回到旧位置

这是小提琴中的代码:

   <div class="drop-target">
        <div class="drag-item" object-id="0"></div>
        <div class="drag-item" style="left: 32px;" object-id="1"></div>
    </div>
var objects = [
    [0, 0],
    [1, 1]
];

$(function() {
    $(".drag-item").draggable({
        grid: [ 32, 32 ],
        containment: '.drop-target',
        drag: function (event, obj){
            let objectId = $(this).attr('object-id');

            var objectPositionX = $(this).position().left / 32;
            var objectPositionY = $(this).position().top / 32;

            var previousPositionX = Math.floor(objects[objectId][0]);
            var previousPositionY = Math.floor(objects[objectId][1]);

            if (objectPositionX != previousPositionX || objectPositionY != previousPositionY) {
                if(!isObjectInPosition(objects, [objectPositionX, objectPositionY])) {
                    objects[objectId] = [objectPositionX, objectPositionY];
                } else {
                    obj.position.left = previousPositionX * 32;
                    obj.position.top = previousPositionY * 32;
                }
            }
        }
    });
});


function isObjectInPosition(arrayToSearch, positionToFind)
{
    for (let i = 0; i < arrayToSearch.length; i++) {
        if (arrayToSearch[i][0] == positionToFind[0]
                && arrayToSearch[i][1] == positionToFind[1]) {
            return true;
        }
    }
    return false;
}
.drag-item {
    background-image: url("http://i.imgur.com/lBIWrWw.png");
    background-size: 32px auto;
    width: 32px;
    height: 32px;
    cursor: move;
}

.drop-target {
    background: whitesmoke url("http://i.imgur.com/uUvTRLx.png") repeat scroll 0 0 / 32px 32px;
    border: 1px dashed orange;
    height: 736px;
    left: 0;
    position: absolute;
    top: 0;
    width: 736px;
}
HTML:

   <div class="drop-target">
        <div class="drag-item" object-id="0"></div>
        <div class="drag-item" style="left: 32px;" object-id="1"></div>
    </div>
var objects = [
    [0, 0],
    [1, 1]
];

$(function() {
    $(".drag-item").draggable({
        grid: [ 32, 32 ],
        containment: '.drop-target',
        drag: function (event, obj){
            let objectId = $(this).attr('object-id');

            var objectPositionX = $(this).position().left / 32;
            var objectPositionY = $(this).position().top / 32;

            var previousPositionX = Math.floor(objects[objectId][0]);
            var previousPositionY = Math.floor(objects[objectId][1]);

            if (objectPositionX != previousPositionX || objectPositionY != previousPositionY) {
                if(!isObjectInPosition(objects, [objectPositionX, objectPositionY])) {
                    objects[objectId] = [objectPositionX, objectPositionY];
                } else {
                    obj.position.left = previousPositionX * 32;
                    obj.position.top = previousPositionY * 32;
                }
            }
        }
    });
});


function isObjectInPosition(arrayToSearch, positionToFind)
{
    for (let i = 0; i < arrayToSearch.length; i++) {
        if (arrayToSearch[i][0] == positionToFind[0]
                && arrayToSearch[i][1] == positionToFind[1]) {
            return true;
        }
    }
    return false;
}
.drag-item {
    background-image: url("http://i.imgur.com/lBIWrWw.png");
    background-size: 32px auto;
    width: 32px;
    height: 32px;
    cursor: move;
}

.drop-target {
    background: whitesmoke url("http://i.imgur.com/uUvTRLx.png") repeat scroll 0 0 / 32px 32px;
    border: 1px dashed orange;
    height: 736px;
    left: 0;
    position: absolute;
    top: 0;
    width: 736px;
}
谢谢,非常感谢您的帮助


托比。

如果您愿意修改draggable本身,我认为这将使逻辑更易于应用。一旦触发拖动事件,您可以执行很多操作,但是如果您修改Dragable的\u generatePosition方法,您将拥有更多的控制权。一开始看起来可能更复杂,但对于这种行为,有时更容易操作

基本上,您可以在应用网格和安全壳检查后运行isInPosition功能。通常下一步是设置新位置,但如果isInPosition返回true,则会阻止拖动。大概是这样的:

'use strict'
// This is the function generating the position by calculating
// mouse position, different offsets and option.

$.ui.draggable.prototype._generatePosition = function(event, constrainPosition) {
  var containment, co, top, left,
    o = this.options,
    scrollIsRootNode = this._isRootNode(this.scrollParent[0]),
    pageX = event.pageX,
    pageY = event.pageY;

  // Cache the scroll
  if (!scrollIsRootNode || !this.offset.scroll) {
    this.offset.scroll = {
      top: this.scrollParent.scrollTop(),
      left: this.scrollParent.scrollLeft()
    };
  }

  /*
   * - Position constraining -
   * Constrain the position to a mix of grid, containment.
   */

  // If we are not dragging yet, we won't check for options
  if (constrainPosition) {

    if (this.containment) {
      if (this.relativeContainer) {
        co = this.relativeContainer.offset();
        containment = [
          this.containment[0] + co.left,
          this.containment[1] + co.top,
          this.containment[2] + co.left,
          this.containment[3] + co.top
        ];
      } else {
        containment = this.containment;
      }

      if (event.pageX - this.offset.click.left < containment[0]) {
        pageX = containment[0] + this.offset.click.left;
      }
      if (event.pageY - this.offset.click.top < containment[1]) {
        pageY = containment[1] + this.offset.click.top;
      }
      if (event.pageX - this.offset.click.left > containment[2]) {
        pageX = containment[2] + this.offset.click.left;
      }
      if (event.pageY - this.offset.click.top > containment[3]) {
        pageY = containment[3] + this.offset.click.top;
      }
    }

    if (o.grid) {

      //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
      top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
      pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;

      left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
      pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
    }

    if (o.axis === "y") {
      pageX = this.originalPageX;
    }

    if (o.axis === "x") {
      pageY = this.originalPageY;
    }
  }

// This is the only part added to the original function.
// You have access to the updated position after it's been
// updated through containment and grid, but before the
// element is modified.
// If there's an object in position, you prevent dragging.

  if (isObjectInPosition(objects, [pageX - this.offset.click.left - this.offset.parent.left, pageY - this.offset.click.top - this.offset.parent.top])) {
    return false;

  }

  return {
    top: (
      pageY - // The absolute mouse position
      this.offset.click.top - // Click offset (relative to the element)
      this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
      this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
      (this.cssPosition === "fixed" ? -this.offset.scroll.top : (scrollIsRootNode ? 0 : this.offset.scroll.top))
    ),
    left: (
      pageX - // The absolute mouse position
      this.offset.click.left - // Click offset (relative to the element)
      this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
      this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
      (this.cssPosition === "fixed" ? -this.offset.scroll.left : (scrollIsRootNode ? 0 : this.offset.scroll.left))
    )
  };

}

var objects = [
  [0, 0],
  [1, 1]
];

$(function() {
  $(".drag-item").draggable({
    grid: [32, 32],
    containment: '.drop-target',
    // on start you remove coordinate of dragged item
    // else it'll check its own coordinates
    start: function(event, obj) {
      var objectId = $(this).attr('object-id');
      objects[objectId] = [null, null];
    },
    // on stop you update your array
    stop: function(event, obj) {
      var objectId = $(this).attr('object-id');
      var objectPositionX = $(this).position().left / 32;
      var objectPositionY = $(this).position().top / 32;
      objects[objectId] = [objectPositionX, objectPositionY];

    }
  });
});


function isObjectInPosition(arrayToSearch, positionToFind) {

  for (let i = 0; i < arrayToSearch.length; i++) {
    if (arrayToSearch[i][0] === (positionToFind[0] / 32) && arrayToSearch[i][1] === (positionToFind[1] / 32)) {

      return true;
    }
  }
  return false;
}
“严格使用”
//这是通过计算生成位置的函数
//鼠标位置、不同的偏移和选项。
$.ui.draggable.prototype._generatePosition=函数(事件、位置){
var安全壳,co,顶部,左侧,
o=此选项,
scrollIsRootNode=this.\u isRootNode(this.scrollParent[0]),
pageX=event.pageX,
pageY=event.pageY;
//缓存滚动条
如果(!scrollIsRootNode | |!this.offset.scroll){
this.offset.scroll={
top:this.scrollParent.scrollTop(),
左:this.scrollParent.scrollLeft()
};
}
/*
*-位置约束-
*将该位置约束为栅格、安全壳的混合。
*/
//如果我们还没有拖动,我们将不会检查选项
如果(约束位置){
如果(本安全壳){
if(此相对容器){
co=this.relativeContainer.offset();
遏制=[
这个.安全壳[0]+一氧化碳左,
本安全壳[1]+co.top,
这是安全壳[2]+一氧化碳左,
这是安全壳[3]+co.top
];
}否则{
遏制=这是遏制;
}
if(event.pageX-this.offset.click.leftcontainment[2]){
pageX=包容[2]+this.offset.click.left;
}
if(event.pageY-this.offset.click.top>containment[3]){
pageY=包容[3]+this.offset.click.top;
}
}
if(o.grid){
//检查网格元素是否设置为0,以防止被0除的错误导致IE中的无效参数错误(请参阅票据#6950)
top=o.grid[1]?this.originalpage+Math.round((pageY-this.originalpage)/o.grid[1])*o.grid[1]:this.originalpage;
pageY=安全壳?((top-this.offset.click.top>=安全壳[1]| top-this.offset.click.top>安全壳[3])?top:((top-this.offset.click.top>=安全壳[1])?top-o.grid[1]:top+o.grid[1]):top;
left=o.grid[0]?this.originalPageX+Math.round((pageX-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX;
pageX=包容?((left-this.offset.click.left>=包容[0]| | left-this.offset.click.left>包容[2])?left:((left-this.offset.click.left>=包容[0])?left-o.grid[0]:left+o.grid[0]):left;
}
如果(o轴==“y”){
pageX=this.originalPageX;
}
如果(o轴==“x”){
pageY=此。原始页面;
}
}
//这是唯一添加到原始函数的部分。
//更新后的职位被删除后,您可以访问该职位
//通过安全壳和网格更新,但在
//元素被修改。
//如果位置上有对象,则可以防止拖动。
if(isObjectInPosition(对象[pageX-this.offset.click.left-this.offset.parent.left,pageY-this.offset.click.top-this.offset.parent.top])){
返回false;
}
返回{
顶部:(
pageY-//鼠标的绝对位置
this.offset.click.top-//单击偏移(相对于元素)
this.offset.relative.top-//仅适用于相对定位的节点:从元素到偏移父节点的相对偏移
this.offset.parent.top+//offsetParent的无边框偏移(offset+border)
(this.cssposposition==“fixed”?-this.offset.scroll.top:(scrollIsRootNode?0:this.offset.scroll.top))
),
左:(
pageX-//鼠标的绝对位置
this.offset.click.left-//单击偏移(相对于元素)
this.offset.relative.left-//仅适用于相对定位的节点:从元素到偏移父节点的相对偏移
this.offset.parent.left+//offsetParent的无边框偏移(offset+border)
(this.cssposposition==“fixed”?-this.offset.scroll.left:(scrollIsRootNode?0:this.offset.scroll.left))
)
};
}
变量对象=[
[0, 0],
[1, 1]
];
$(函数(){
$(“.drag项”).draggable({
网格:[32,32],
包含:'.drop目标',
//开始时,删除拖动项目的坐标
//否则它会检查自己的坐标
启动:功能(事件,obj){
var objectId=$(this.attr('object-id');
objects[objectId]=[null,null];
},
//停止时更新阵列
停止:功能(事件,obj){
var objectId=$(this.attr('object-id');