如何倾斜/旋转在javascript拖放中拖动的项目?

Posted

技术标签:

【中文标题】如何倾斜/旋转在javascript拖放中拖动的项目?【英文标题】:How to tilt/rotate the item being dragged in javascript drag and drop? 【发布时间】:2017-09-15 08:46:38 【问题描述】:

我想倾斜被拖动的项目以显示区别。我在这里有基本的拖放小提琴https://jsfiddle.net/igaurav/bqprc9p8/3/

我的 javascript 看起来像:

"use strict";

var source = null;

function listItemDragStartHandler(event)
    // What is true there for?
    source = event.currentTarget;
    event.dataTransfer.setData("text/plain", event.currentTarget.innerhtml);
    event.currentTarget.style.transform = 'rotate(15deg)';
    event.dataTransfer.effectAllowed = "move";


function dragoverHandler(event) 
    event.preventDefault();
    event.dataTransfer.dropEffect = "move";


function dropHandler(event) 
    event.preventDefault();
    event.stopPropagation();
    var currentElement = event.currentTarget;
    var listContainer = currentElement.parentNode;
    listContainer.insertBefore(source, currentElement);
    source.style.transform = 'rotate(0deg)';


function delete_item(event) 
    var currentTarget = event.currentTarget;
    var grandParentOfDelete = currentTarget.parentNode.parentNode;
    grandParentOfDelete.remove();


function add_item() 
    var item_text_node = document.getElementsByName("add-item-text")[0]
    var item_text = item_text_node.value;
    if (item_text.length > 0) 
        var item_template = document.getElementById("item-template");
        var item_clone = item_template.cloneNode(true);
        item_clone.removeAttribute("id");
        var clone_text = item_clone.getElementsByClassName("item-text")[0];
        clone_text.textContent = item_text;
        // reset the value
        item_text_node.value = "";
        var item_list = document.getElementById("item-list");
        item_list.appendChild(item_clone);
     else 
        alert("No text?? Add some text!");
    


function add_item_listener() 
    var add_item_button = document.getElementById("add-item");
    add_item_button.addEventListener("click", add_item);


function sample_data() 
    for(var i=0;i<10;i++)
        var item_text_node = document.getElementsByName('add-item-text')[0]
        item_text_node.value = i;
        add_item();
    


function init_app() 
    add_item_listener();
    sample_data();


window.onload = function () 
    init_app()

相关的 HTML 是:

<body>
    <div id="container">
        <div id="add-item-div">
            <input type="text" name="add-item-text">
            <button id="add-item">Add Item</button>
        </div>
        <div id="item-list">
        </div>
        <div id="item-template" class="item-list-element" draggable="true" ondragstart="listItemDragStartHandler(event);" ondrop="dropHandler(event);" ondragover="dragoverHandler(event);">
            <div class="item-text"></div>
            <div class="delete-item-div">
                <button class="delete-item" onclick="delete_item(event);">Delete Item</button>
            </div>
        </div>
    </div>
</body>

我正在9 行上应用变换,但拖动操作停止并且没有开始拖动。

我做错了什么?

P.S:我不想使用库。

【问题讨论】:

小提琴不起作用 @elpddev 我的错,修复了小提琴,不得不在小提琴中将负载类型指定为“No wrap ”。谢谢 【参考方案1】:

基本上,我们可以使用setDragImage 来替换浏览器实现的为拖动操作而呈现的幽灵图像,使用我们自己的实现。

我们使用一个克隆节点,就像你在小提琴中所做的那样,我们将它添加到 dom 中。

然后,您可以对克隆元素中的内部容器进行转换。

document.getElementById("drag-with-create-add").addEventListener("dragstart", function(e) 
    var crt = this.cloneNode(true);

    crt.style.position = "absolute"; 
    crt.style.top = "0px"; 
    crt.style.left = "-100px";
    
    var inner = crt.getElementsByClassName("inner")[0];
    inner.style.backgroundColor = "orange";
    inner.style.transform = "rotate(20deg)";
    
    document.body.appendChild(crt);
    e.dataTransfer.setDragImage(crt, 20, 20);
, false);
<div id="drag-with-create-add" class="dragdemo" draggable="true">
  <div class="inner">
    drag me
  </div>
</div>

这部分基于 Stuart Langridge 的 helpfull article。

注意:这里的技巧是在内部元素上应用转换,而不是在具有拖动事件的元素上。只有应用于内部元素时才会出现转换。

【讨论】:

抱歉回复晚了。您的解决方案有效,这正是我所需要的。这里的技巧是对内部元素应用转换,而不是对具有拖动事件的元素应用转换。如果应用于内部元素,则会出现转换,您已经这样做了。谢谢。【参考方案2】:

我刚刚创建了一个示例fiddle。它使用setDragImage 方法,请查看并评论您的需求,以便我们更新答案。

我添加了一个重影图像,并在拖动开始时添加了“摇晃”的感觉。您也可以通过 css 类似地旋转拖动的幻像。

另外请注意,我们正在克隆图像,同时拖动以显示重影图像。所以我们需要手动从 dom 中删除它。

document.addEventListener("dragstart", function(e) 
  var img = document.createElement("img");
  img.src = "http://i.imgur.com/BDcvqmf.jpg";
  e.dataTransfer.setDragImage(img, 5000, 5000); //5000 will be out of the window
  drag(e)
, false);

var crt, dragX, dragY;
//document.addEventListener('drag',drag)
function drag(ev) 
  crt = ev.target.cloneNode(true);
  crt.className = "face";
  crt.style.position = "absolute";
  crt.style.opacity = "0.9";
  document.body.appendChild(crt);
  ev.dataTransfer.setData("text", ev.target.id);


document.addEventListener("dragover", function(ev) 
  ev = ev || window.event;
  dragX = ev.pageX;
  dragY = ev.pageY;
  crt.style.left = dragX + "px";
  crt.style.top = dragY + "px";
, false);

document.addEventListener("dragend", function(event) 
  crt.style.display = 'none';
  crt.remove()
);
body 
  padding: 10px


#draggable-element 
  width: 100px;
  height: 100px;
  background-color: #666;
  color: white;
  padding: 10px 12px;
  cursor: move;
  position: relative;
  /* important (all position that's not `static`) */


.face 
  animation: shake 1s cubic-bezier(.36, .07, .19, .97) both;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  perspective: 1000px;


@keyframes shake 
  10%,
  90% 
    transform: translate3d(-1px, 0, 0);
  
  20%,
  80% 
    transform: translate3d(4px, 0, 0);
  
  30%,
  50%,
  70% 
    transform: translate3d(-5px, 0, 0);
  
  40%,
  60% 
    transform: translate3d(5px, 0, 0);
  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

See the tilt in action on drag start. <br>

<img draggable id="draggable-element" src="http://i.imgur.com/BDcvqmf.jpg">

【讨论】:

谢谢,我实际上想在 HTML 元素上使用它。但这也是很好的参考。

以上是关于如何倾斜/旋转在javascript拖放中拖动的项目?的主要内容,如果未能解决你的问题,请参考以下文章

如果图像是链接,如何从拖放中获取图像 URL?

在 Qt 拖放中使用 QMimeData 传递数据

如何在拖放中停止 dragend 的默认行为?

在 ember 中,如何将视图数据从拖放中传递?

在 Angular Material CDK 拖放中,如何防止项目随着元素移动而自动重新排列?

拖放与物理行为