jQuery UI (Droppable) :如果 droppable 具有 css 相对/绝对位置,则可拖动元素未放置在鼠标指针处

jQuery UI (Droppable) : Draggable element not placed at mouse pointer if droppable has css position relative / absolute

我正在使用 jquery ui 拖放。

如果 droppable div (#dropContainer) 具有 css 相对/绝对/固定位置,则放置的元素不会放置在我的鼠标指针上。

<div id="dropContainer" style="position:relative;"></div>

If I remove the position for droppable div, it is working as expected. But need to use the position for some obvious reasons

draggableInputNo = 0;

var buttonElement = '<div class="button" style="width:200px;">Button</div>'
var textElement = '<div class="text">Text Element</div>'

$(function() {
  $("#dropContainer").droppable({
    drop: function(event, ui) {
      $element = ui.helper.clone();
      $element.resizable();
      $element.draggable();
      $element.selectable();

      if (ui.draggable.hasClass('draggableInput text')) {
        draggableInputNo++;
        $element.attr("id", 'draggableInput' + draggableInputNo);
        $element.appendTo(this);
        $element.append(textElement);
      }
      else if (ui.draggable.hasClass('draggableInput button')) {
        draggableInputNo++;
        $element.attr("id", 'draggableInput' + draggableInputNo);
        $element.appendTo(this);
        $element.append(buttonElement);
      }
    }
  });

  $(".draggableInput").draggable({
    //containment: '#rpWebPushPopupContainer',
    cursor: 'move',
    helper: draggableInputHelper,
  });

});

function draggableInputHelper(event) {
  return '<div id="draggableInput' + draggableInputNo + '" class="draggableInputHelper resizable" ></div>'
}
.draggableInput {
  width: 50px;
  height: 30px;
  padding: 1em;
  float: left;
  margin: 10px 10px 10px 0;
  background-color: #9933ff;
  border-radius: 10px;
  border: 1px solid #9933ff;
}

.draggableInputHelper {
  width: 100px;
  height: 30px;
  padding: 0.5em;
  margin: 10px 10px 10px 0;
  background-color: #006699;
  border-radius: 10px;
  border: 1px solid #006699;
  color:#ffffff;
}

#dropContainer {
  width: 300px;
  height: 200px;
  padding: 0.5em;
  margin: 10px;
  float: left;
  border: 1px solid #867979;
  border-radius: 4px;
  background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.9.1/jquery-ui.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.9.1/themes/base/jquery-ui.min.css" />

<div class="draggableInput text">Text</div>
<div class="draggableInput button">Button</div>

<div id="dropContainer" style="position:relative;"></div>

当您在 divrelative 中放置可放置元素时,包含在可放置元素中的元素会不必要地向其添加父元素的偏移位置。所以删除掉回调函数中多余的offset

如下所示调整您的位置。

var parent = $('#dropContainer.ui-droppable');
var leftAdjust = $element.position().left - parent.offset().left;
var topAdjust = $element.position().top - parent.offset().top;
$element.css({
      left: leftAdjust,
      top: topAdjust
      })

draggableInputNo = 0;

var buttonElement = '<div class="button" style="width:200px;">Button</div>'
var textElement = '<div class="text">Text Element</div>'

$(function() {
  $("#dropContainer").droppable({
    drop: function(event, ui) {
      $element = ui.helper.clone();
      $element.resizable();
      $element.draggable();
      $element.selectable();

      if (ui.draggable.hasClass('draggableInput text')) {
        draggableInputNo++;
        $element.attr("id", 'draggableInput' + draggableInputNo);
        $element.appendTo(this);
        $element.append(textElement);
        var parent = $('#dropContainer.ui-droppable');
        var leftAdjust = $element.position().left - parent.offset().left;
        var topAdjust = $element.position().top - parent.offset().top;
        $element.css({
          left: leftAdjust,
          top: topAdjust
        });
      } else if (ui.draggable.hasClass('draggableInput button')) {
        draggableInputNo++;
        $element.attr("id", 'draggableInput' + draggableInputNo);
        $element.appendTo(this);
        $element.append(buttonElement);
        var parent = $('#dropContainer.ui-droppable');
        var leftAdjust = $element.position().left - parent.offset().left;
        var topAdjust = $element.position().top - parent.offset().top;
        $element.css({
          left: leftAdjust,
          top: topAdjust
        });
      }
    }
  });

  $(".draggableInput").draggable({
    //containment: '#rpWebPushPopupContainer',
    cursor: 'move',
    helper: draggableInputHelper,
  });

});

function draggableInputHelper(event) {
  return '<div id="draggableInput' + draggableInputNo + '" class="draggableInputHelper resizable" ></div>'
}
.draggableInput {
  width: 50px;
  height: 30px;
  padding: 1em;
  float: left;
  margin: 10px 10px 10px 0;
  background-color: #9933ff;
  border-radius: 10px;
  border: 1px solid #9933ff;
}

.draggableInputHelper {
  width: 100px;
  height: 30px;
  padding: 0.5em;
  margin: 10px 10px 10px 0;
  background-color: #006699;
  border-radius: 10px;
  border: 1px solid #006699;
  color: #ffffff;
}

#dropContainer {
  width: 300px;
  height: 200px;
  padding: 0.5em;
  margin: 10px;
  float: left;
  border: 1px solid #867979;
  border-radius: 4px;
  background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.9.1/jquery-ui.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.9.1/themes/base/jquery-ui.min.css" />

<div class="draggableInput text">Text</div>
<div class="draggableInput button">Button</div>

<div id="dropContainer" style="position:relative;"></div>

这是另一个例子,基于您上面已有的答案。

$(function() {
  function draggableInputHelper(event) {
    return $("<div>", {
      id: "draggableInput" + draggableInputNo,
      class: "draggableInputHelper resizable"
    });
  }

  function correctDrop(ui, par) {
    return {
      top: (ui.position.top - $(par).offset().top) + "px",
      left: (ui.position.left - $(par).offset().left) + "px"
    }
  }

  var draggableInputNo = 0;

  var buttonElement = $("<div>", {
      class: "button"
    })
    .css("width", "200px")
    .html("Button");
  var textElement = $("<div>", {
    class: "text"
  }).html("Text Element");

  $("#dropContainer").droppable({
    drop: function(event, ui) {
      $element = ui.helper.clone();
      $element.attr("id", 'draggableInput' + ++draggableInputNo);
      $element.css(correctDrop(ui, $("#dropContainer"))).appendTo(this);
      if (ui.draggable.hasClass('draggableInput text')) {
        $element.append(textElement);
      } else if (ui.draggable.hasClass('draggableInput button')) {
        $element.append(buttonElement);
      }
      $element.resizable();
      $element.draggable();
      $element.selectable();
    }
  });

  $(".draggableInput").draggable({
    cursor: 'move',
    helper: draggableInputHelper,
  });
});
.draggableInput {
  width: 50px;
  height: 30px;
  padding: 1em;
  float: left;
  margin: 10px 10px 10px 0;
  background-color: #9933ff;
  border-radius: 10px;
  border: 1px solid #9933ff;
}

.draggableInputHelper {
  width: 100px;
  height: 30px;
  padding: 0.5em;
  margin: 10px 10px 10px 0;
  background-color: #006699;
  border-radius: 10px;
  border: 1px solid #006699;
  color: #ffffff;
}

#dropContainer {
  width: 300px;
  height: 200px;
  padding: 0.5em;
  margin: 10px;
  float: left;
  border: 1px solid #867979;
  border-radius: 4px;
  background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.9.1/jquery-ui.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.9.1/themes/base/jquery-ui.min.css" />

<div class="draggableInput text">Text</div>
<div class="draggableInput button">Button</div>

<div id="dropContainer" style="position:relative;"></div>

这只是压缩了一些代码。编写小函数可以更轻松地应用所需的一些更改。