jQuery UI Drag/Drop, snap to bottom

浪子不回头ぞ 提交于 2019-12-08 03:52:50

问题


So, based on this answer, I've got a set of divs that can drag/drop and snap into place. The only problem is, the draggable divs have different heights, and I need them to always snap to the bottom of the target, instead of the top.

You can see a demo of the markup and the problem I'm having in this JsFiddle.

The markup is like this:

<!-- Slots are droppable targets -->
<div class="devices">
  <div class="slot" id="slot_10">
    <span class="text">Slot 10</span>
  </div>
  <div class="slot" id="slot_9">
    <span class="text">Slot 9</span>
  </div>
  ...
</div>
<!-- .device is draggable -->
<div class="products">
  <div class="device" data-height="2" id="device_1">
    Device 1
  </div>
  <div class="device" data-height="1" id="device_2">
    Device 2
  </div>
  ...
</div>

Here is the JS portion:

$(function(){
  $('.device').draggable({});
  $('.slot, .products').droppable({
    hoverClass: 'active',
    drop: function(event, ui) {
      console.log("Dropped:",ui.draggable.attr('id'),"on:",$(this).attr('id'));
      $(ui.draggable).detach().css({top:'',left:0,bottom:0}).appendTo(this);
    }
  });
});

Here is the CSS

.sample-ui { margin: 40px auto 0; width: 700px; }
.cabinet { width: 335px; float: left; margin-right: 65px; }
.rack { width: 30px; margin-right: 5px; float: left; }
.devices { float: left; width: 300px; }
.bolt, .device, .slot {
  position: relative;
  height: 30px; line-height: 30px; text-align: center; background: #FFF;
  margin-bottom: 5px;
}
.slot { background: #EEE; }
.slot .text { display: block; position: absolute; width: 100%; top: 0; left: 0; }
.active { border: 1px solid #F00; }
.device { z-index: 100; }
.device[data-height="2"] { height: 65px; }
.device[data-height="3"] { height: 100px; }

.catalogue {
  width: 300px; float: left;
}

It seems to me like if on div is positioned absolute bottom 0 inside of a relative positioned div, it should be snapped to the bottom... but that's not what's happening. What am I overlooking here?


回答1:


I was just playing with something similar for another question and I think the same approach may work for you.

Basically I figured out a way to add new snapModes to jQuery-UI.

You will need to edit the jQuery-ui file, but I think it may be worth it.

In addition to the standard inner, outer, and both. I added the following options:

  • innerTop
  • innerBottom
  • innerLeft
  • InnerRight
  • outerTop
  • outerBottom
  • outerRight
  • outerLeft

Working Example

Here's how:

Search for:

if(o.snapMode != 'inner') {
                var ts = Math.abs(t - y2) <= d;
                var bs = Math.abs(b - y1) <= d;
                var ls = Math.abs(l - x2) <= d;
                var rs = Math.abs(r - x1) <= d;
                if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
                if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
                if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
                if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
            }

            var first = (ts || bs || ls || rs);

            if(o.snapMode != 'outer') {
                var ts = Math.abs(t - y1) <= d;
                var bs = Math.abs(b - y2) <= d;
                var ls = Math.abs(l - x1) <= d;
                var rs = Math.abs(r - x2) <= d;
                if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
                if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
                if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
                if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
            }

and replace it with:

if (o.snapMode != 'inner' && o.snapMode != 'innerTop' && o.snapMode != 'innerBottom' && o.snapMode != 'innerLeft' && o.snapMode != 'innerRight' && o.snapMode != 'outerTop' && o.snapMode != 'outerBottom' && o.snapMode != 'outerLeft' && o.snapMode != 'outerRight') {
    var ts = Math.abs(t - y2) <= d;
    var bs = Math.abs(b - y1) <= d;
    var ls = Math.abs(l - x2) <= d;
    var rs = Math.abs(r - x1) <= d;
    if (ts) ui.position.top = inst._convertPositionTo("relative", {
        top: t - inst.helperProportions.height,
        left: 0
    }).top - inst.margins.top;
    if (bs) ui.position.top = inst._convertPositionTo("relative", {
        top: b,
        left: 0
    }).top - inst.margins.top;
    if (ls) ui.position.left = inst._convertPositionTo("relative", {
        top: 0,
        left: l - inst.helperProportions.width
    }).left - inst.margins.left;
    if (rs) ui.position.left = inst._convertPositionTo("relative", {
        top: 0,
        left: r
    }).left - inst.margins.left;
}

var first = (ts || bs || ls || rs);

if (o.snapMode != 'outer' && o.snapMode != 'innerTop' && o.snapMode != 'innerBottom' && o.snapMode != 'innerLeft' && o.snapMode != 'innerRight' && o.snapMode != 'outerTop' && o.snapMode != 'outerBottom' && o.snapMode != 'outerLeft' && o.snapMode != 'outerRight') {
    var ts = Math.abs(t - y1) <= d;
    var bs = Math.abs(b - y2) <= d;
    var ls = Math.abs(l - x1) <= d;
    var rs = Math.abs(r - x2) <= d;
    if (ts) ui.position.top = inst._convertPositionTo("relative", {
        top: t,
        left: 0
    }).top - inst.margins.top;
    if (bs) ui.position.top = inst._convertPositionTo("relative", {
        top: b - inst.helperProportions.height,
        left: 0
    }).top - inst.margins.top;
    if (ls) ui.position.left = inst._convertPositionTo("relative", {
        top: 0,
        left: l
    }).left - inst.margins.left;
    if (rs) ui.position.left = inst._convertPositionTo("relative", {
        top: 0,
        left: r - inst.helperProportions.width
    }).left - inst.margins.left;
}

if (o.snapMode == 'innerTop') {
    var ts = Math.abs(t - y1) <= d;
    if (ts) ui.position.top = inst._convertPositionTo("relative", {
        top: t,
        left: 0
    }).top - inst.margins.top;
}

if (o.snapMode == 'innerBottom') {
    var bs = Math.abs(b - y2) <= d;
    if (bs) ui.position.top = inst._convertPositionTo("relative", {
        top: b - inst.helperProportions.height,
        left: 0
    }).top - inst.margins.top;
}

if (o.snapMode == 'innerLeft') {
    var ls = Math.abs(l - x1) <= d;
    if (ls) ui.position.left = inst._convertPositionTo("relative", {
        top: 0,
        left: l
    }).left - inst.margins.left;
}

if (o.snapMode == 'innerRight') {
    var rs = Math.abs(r - x2) <= d;
    if (rs) ui.position.left = inst._convertPositionTo("relative", {
        top: 0,
        left: r - inst.helperProportions.width
    }).left - inst.margins.left;
}


if (o.snapMode == 'outerTop') {
    var ts = Math.abs(t - y2) <= d;
    if (ts) ui.position.top = inst._convertPositionTo("relative", {
        top: t - inst.helperProportions.height,
        left: 0
    }).top - inst.margins.top;
}

if (o.snapMode == 'outerBottom') {
    var bs = Math.abs(b - y1) <= d;
    if (bs) ui.position.top = inst._convertPositionTo("relative", {
        top: b,
        left: 0
    }).top - inst.margins.top;
}

if (o.snapMode == 'outerLeft') {
    var ls = Math.abs(l - x2) <= d;
    if (ls) ui.position.left = inst._convertPositionTo("relative", {
        top: 0,
        left: l - inst.helperProportions.width
    }).left - inst.margins.left;
}

if (o.snapMode == 'outerRight') {
    var rs = Math.abs(r - x1) <= d;
    if (rs) ui.position.left = inst._convertPositionTo("relative", {
        top: 0,
        left: r
    }).left - inst.margins.left;
}


来源:https://stackoverflow.com/questions/18294487/jquery-ui-drag-drop-snap-to-bottom

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!