以编程方式将元素拖放到另一个元素上

问题描述 投票:0回答:3

使用 jQuery UI,是否可以使用 javascript 执行拖放操作?

示例。单击链接后,将

#pony
拖放到
#box
中。我尝试过触发拖动事件,但这似乎不起作用:)

$('#pony').trigger('drag', [$('#box')]);
javascript jquery jquery-ui draggable droppable
3个回答
19
投票

这就是 jQuery UI 团队以编程方式触发

drop
事件的方式。

droppable_events.js

draggable = $( "#draggable1" ).draggable(),
droppable1 = $( "#droppable1" ).droppable( config ),
droppable2 = $( "#droppable2" ).droppable( config ),

droppableOffset = droppable1.offset(),
draggableOffset = draggable.offset(),
dx = droppableOffset.left - draggableOffset.left,
dy = droppableOffset.top - draggableOffset.top;

draggable.simulate( "drag", {
    dx: dx,
    dy: dy
});

simulate
函数在jquery.simulate.js中定义。简而言之,它将可拖动对象移动到可放置对象上以触发
drop
事件。

总而言之,我们有以下片段。干杯。

$(function() {
  $("#draggable").draggable();
  $("#droppable").droppable({
    drop: function(event, ui) {
      console.log(event, ui);
      alert('dropped!');
    }
  });
});

function trigger_drop() {
  var draggable = $("#draggable").draggable(),
    droppable = $("#droppable").droppable(),

    droppableOffset = droppable.offset(),
    draggableOffset = draggable.offset(),
    dx = droppableOffset.left - draggableOffset.left,
    dy = droppableOffset.top - draggableOffset.top;

  draggable.simulate("drag", {
    dx: dx,
    dy: dy
  });
}
#draggable {
  width: 100px;
  height: 100px;
  padding: 0.5em;
  float: left;
  margin: 10px 10px 10px 0;
}
#droppable {
  width: 150px;
  height: 150px;
  padding: 0.5em;
  float: left;
  margin: 10px;
}
br {
  clear: both;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/smoothness/jquery-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script>

<script src="https://rawgit.com/jquery/jquery-ui/1-11-stable/external/jquery-simulate/jquery.simulate.js"></script>


<div id="draggable" class="ui-widget-content">
  <p>Drag me to my target</p>
</div>

<div id="droppable" class="ui-widget-header">
  <p>Drop here</p>
</div>
<br>
<button onclick="trigger_drop()">trigger drop event</button>


2
投票
  • 如果您想触发与实际通过鼠标放置对象时发生的相同功能,您可以将放置脚本封装到一个函数中,然后您也可以在其他地方简单地调用该函数。

  • 如果您希望项目被拖放时有动画效果,您应该将其

    .stop().animate({})
    移动到目标位置,然后执行上述步骤。

  • 如果您只是想将其附加到放置目标,只需

    .appendTo($('#yourtargetid'));

抱歉,如果我误解了什么,我的声誉点不足以提前询问你,就像我在其他地方所做的那样。


0
投票

如果你想使用 HTML 可拖动元素来做到这一点,而不需要 jquery,你需要用你自己的类来模拟 google chrome dataTransfer API,因为 google 不希望你创建自己的 dataTransfer 实例。

function simulateDragAndDrop(sourceNode, destinationNode) {


 class MyDataTransfer {
        constructor() {
            this.dropEffect = "all";
            this.effectAllowed = "all";
            this.files = [];
            this.items = new DataTransferItemList();
            this.types = [];
        }
        setData(format, data) {
            this.data[format] = data;
        }
        getData(format) {
            return this.data[format];
        }
        clearData(format = null) {
            if (format) {
                delete this.data[format];
            } else {
                this.data = {};
            }
        }
        clearData(type) {
            if (type) {
                const index = this.types.indexOf(type);
                if (index !== -1) {
                    this.types.splice(index, 1);
                }
            } else {
                this.types = [];
            }
        }

        getData(type) {
            const index = this.types.indexOf(type);
            return index !== -1 ? this.items[index].data : '';
        }

        setData(type, data) {
            const index = this.types.indexOf(type);
            if (index !== -1) {
                this.items[index].data = data;
            } else {
                this.types.push(type);
                this.items.add(new DataTransferItem(type, data));
            }
        }

        setDragImage(imageElement, x, y) {
            // I do nothing here it's just to avoid errrs
        }
    }

    class DataTransferItem {
        constructor(type, data) {
            this.type = type;
            this.data = data;
        }
    }

    class DataTransferItemList extends Array {
        add(item) {
            this.push(item);
        }
    }
    const EVENT_TYPES = {
        DRAG_END: 'dragend',
        DRAG_START: 'dragstart',
        DROP: 'drop'
    }
    const dataTransfer = new MyDataTransfer();

    function createCustomEvent(type) {
        const event = new CustomEvent(type, {
            bubbles: true,
            cancelable: true
        });
        event.dataTransfer = dataTransfer;
        return event;
    }

    let events = [];

    // let myDataTransfer = new MyDataTransfer();
    events.push(createCustomEvent(EVENT_TYPES.DRAG_START));

    events.push(createCustomEvent(EVENT_TYPES.DROP));

    // Dispatch dragstart and dragend events on the sourceNode
    events.forEach((event) => sourceNode.dispatchEvent(event));

    const dropEvent = createCustomEvent(EVENT_TYPES.DROP);
    destinationNode.dispatchEvent(dropEvent);

}

© www.soinside.com 2019 - 2024. All rights reserved.