【问题标题】:How to trigger droppable event on dragging element over with jQuery UI?如何使用 jQuery UI 在拖动元素时触发可放置事件?
【发布时间】:2020-05-04 08:18:44
【问题描述】:

我正在制作一个大型项目,它应该像每个软件一样在性能方面都不错。但我正在为拖放对象而苦苦挣扎。

让我从我的代码开始。 这是我的 HTML:

<div class="drag-me"></div>
<div class="drop-on-me"></div>

这是我的 JavaScript:

$('.drag-me').draggable();

$('.drop-on-me').hover(function(){
   let el = $(this);
   el.droppable({
      drop: function(){
         console.log("dropped!");
      }
   });
}, function(){
   let el = $(this);
   el.droppable('destroy');
});

Codepen Example

我需要在拖动对象时在悬停时触发可放置事件,因为页面中有太多可放置对象,并且浏览器会消耗大量 RAM 并且页面崩溃。

当我悬停在可拖动对象上时如何触发?

【问题讨论】:

  • 您需要使用.trigger(),但您不希望在悬停事件期间触发drop 事件是有逻辑的。听起来你想初始化 droppable。您应该能够初始化它们并将它们禁用直到悬停。或者只是将可见元素初始化为可放置。

标签: javascript jquery jquery-ui


【解决方案1】:

您需要进行一定程度的碰撞检测。 drag 事件可以阻止一些其他事件,例如 hover 冒泡。考虑以下代码 sn-p。

$(function() {

  function getBounds(el) {
    var p = {
      tl: $(el).position()
    };
    p['tr'] = {
      top: p.tl.top,
      left: p.tl.left + $(el).width()
    };
    p['bl'] = {
      top: p.tl.top + $(el).height(),
      left: p.tl.left
    };
    p['br'] = {
      top: p.bl.top,
      left: p.tr.left
    };
    return p;
  }

  function isOver(el, map) {
    var myPos = getBounds(el);
    var tObj = false;
    $.each(map, function(k, v) {
      if (myPos.tl.left > v.tl.left && myPos.tl.left < v.tr.left && myPos.tl.top > v.tl.top && myPos.tl.top < v.bl.top) {
        console.log("Over", k);
        tObj = $(".drop-on-me").eq(k);
      }
    });
    return tObj;
  }

  function makeDrop(el) {
    if (!$(el).hasClass("ui-droppable")) {
      $(el).droppable({
        addClasses: false,
        drop: function() {
          console.log("Item Dropped.");
        },
        out: function() {
          $(this).droppable("destroy");
        }
      });
    }
  }

  var dropPositions = [];

  $(".drop-on-me:visible").each(function(i, el) {
    dropPositions.push(getBounds(el));
  });

  console.log("Mapping complete.", dropPositions);

  $('.drag-me').draggable({
    start: function() {
      console.log("Drag Start.");
    },
    stop: function() {
      console.log("Drag Stop.");
    },
    drag: function(e, ui) {
      var target = isOver(ui.helper, dropPositions);
      if (target) {
        console.log("Make Drop, Index: " + target.index());
        makeDrop(target);
      }
    }
  });
});
.drag-me {
  width: 30px;
  height: 30px;
  background-color: rgba(255, 0, 0, 0.75);
  border: 1px solid #000;
  border-radius: 3px;
  z-index: 300;
}

.drop-on-me {
  width: 100px;
  height: 100px;
  background-color: rgba(0, 0, 255, 0.75);
  border: 1px solid #000;
  border-radius: 3px;
  position: absolute;
}

.drop-on-me.top {
  left: 80px;
  top: 10px;
}

.drop-on-me.mid {
  left: 40px;
  top: 120px;
}

.drop-on-me.bot {
  left: 240px;
  top: 640px;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="drag-me"></div>
<div class="drop-on-me top"></div>
<div class="drop-on-me mid"></div>
<div class="drop-on-me bot"></div>

【讨论】:

  • 这是我认为最好的解决方案。但是很难用。因为您需要将所有内容设置为静态或相对。但是如果你的应用程序有固定的绝对元素,jQuery 的 position() 函数可能会返回错误的值。感谢您的关心。
  • @sundowatch 是的,如果您愿意,您可以将event 属性用于pageXpageY.position().offset() 更容易调用。
猜你喜欢
  • 2016-04-27
  • 1970-01-01
  • 2021-06-18
  • 2014-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多