删除事件 dataTransfer.getData() 在 Firefox 上返回 ""

Posted

技术标签:

【中文标题】删除事件 dataTransfer.getData() 在 Firefox 上返回 ""【英文标题】:drop event dataTransfer.getData() returns "" on Firefox 【发布时间】:2017-10-26 08:41:31 【问题描述】:

我正在尝试找出为什么我们的 AngularJS 应用程序上的拖放功能在 Firefox 上不起作用,但在 Chrome 上却可以,在研究了一段时间后,我不知道出了什么问题,因为显然它应该工作。

这是放置事件监听器:

    document.addEventListener("drop", function(event) 
        console.log(event);
        event.preventDefault();
        vm.msg = ;
        vm.msg.appName = event.dataTransfer.getData("appName");
        vm.msg.code = event.dataTransfer.getData("code");
        vm.msg.url = event.dataTransfer.getData("url");
        vm.msg.structure = event.dataTransfer.getData("structure");
        console.log(vm.msg);
        dropping(vm.msg);
    );

在 Chrome 上,这可以完美运行。然而,在 Firefox 上,它“有效”。捕获事件,执行代码,even.dataTransfer 具有所有预期类型(appName、代码、url、结构等),为所有这些类型(字符串)正确定义了“种类”......我也看到了 Firebug没问题。

但是event.dataTransfer.getData("appName")(或任何类型)返回空字符串"",并且不会抛出任何错误或警告。我不知道出了什么问题或我错过了什么。


//编辑 2017-05-26:更多信息

因为进行 drop 的模板来自其他应用程序共享的指令,所以我必须从我的控制器应用更改:

    angular.element('#dropSide').bind('dragover', function()

        if (vm.itemsDragging.length === 0)
          vm.itemsDragging = angular.element(' .tree-row.tree-row-type,.tree-row.tree-row-type-level');
        

        angular.forEach(vm.itemsDragging,function(obj)
            $(obj).unbind('dragover');
            $(obj).bind('dragover', function(event)
              vm.node = $(event.currentTarget.children[0].children[0]);
              event.preventDefault();
              $(obj).addClass('dragging');
            );
            $(obj).unbind('dragleave');
            $(obj).bind('dragleave', function(event)
              event.preventDefault();
              $(obj).removeClass('dragging');
            );
            $(obj).unbind('drop');
            $(obj).bind('drop', function(event)
              event.preventDefault();
              $(obj).removeClass('dragging');
            );
        );
    );

这在 Firefox 上运行良好。

拖动的来源是另一个域上的 Angular 应用程序,我们可以这样访问:

  <div class="container-vide">
    <object ng-cloak 
            id="dragsource"
            data="https://vm.dragsourceurl" 
            type="text/html">      
    </object>
  </div>

在该其他域上使用定制的 ng-draggable 指令来填充数据。在 Firefox 上也能正常工作。

        element.bind("dragstart", function (eventObject) 
            console.log('dragstart');
            for (var attr in attributes) 
                if (attr.substring(0, 4) === 'drag') 
                    eventObject.dataTransfer.setData(attr.substring(4).toLowerCase(), attributes[attr]);
                
            

模板

<span ng-draggable 
            drag-appname="App Name" 
            drag-structure="Default Structure"
            drag-code="1" 
            drag-url="mockurl.com"
            class="draggable">
</span> 

//编辑:再次,更多信息

我今天调试了很多东西来玩“寻找差异”游戏,到目前为止我只找到了一个。

对于 Chrome/Firefox,事件的管理完全相同,但我发现(基于此处的答案:HTML5 drop event doesn't work unless dragover is handled)如果我将 dragover 事件的 dropEffect 从 '无”到“复制”

event.originalEvent.dataTransfer.dropEffect = 'copy';

在 Chrome 中,在放置事件时,我得到“无”作为 dropEffect(因此更改对此事件没有影响),但在 Firefox 放置事件中,“复制”作为 dropEffect。

这是迄今为止我发现的唯一区别。

因此,我现在的理论是,我正在通过 Firefox 上的 dragover 事件进入 drop 侦听器,这当然还不允许访问 Data。不过,我不知道为什么会发生这种情况,也不知道如何解决。

【问题讨论】:

【参考方案1】:

请参阅下面的代码,我已经检查过它在 Firefox 中是否正常工作。

function drag(ev) 
    ev.dataTransfer.setData("text", ev.target.id);
    ev.dataTransfer.setData("appName", "Default App");
    ev.dataTransfer.setData("code", "Code - 1");
    ev.dataTransfer.setData("url", "http://www.example.com");
    ev.dataTransfer.setData("structure", "Default Structure");


function drop(event) 
    event.preventDefault();
    var data = event.dataTransfer.getData("text");
    event.target.appendChild(document.getElementById(data));
    var vm = [];
    vm.msg = ;
  vm.msg.appName = event.dataTransfer.getData("appName");
  vm.msg.code = event.dataTransfer.getData("code");
  vm.msg.url = event.dataTransfer.getData("url");
  vm.msg.structure = event.dataTransfer.getData("structure");
  console.log(vm.msg);


function allowDrop(ev) 
    ev.preventDefault();
#div1 
    width: 350px;
    height: 70px;
    padding: 10px;
    border: 1px solid #aaaaaa;
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<label id="lbl" draggable="true" ondragstart="drag(event)">Drop me</label>

【讨论】:

我编辑了我的原始帖子,请看一下。我想我已经像你的例子那样做了。

以上是关于删除事件 dataTransfer.getData() 在 Firefox 上返回 ""的主要内容,如果未能解决你的问题,请参考以下文章

拖放 dataTransfer.getData 为空

使用带拖放的dataTransfer.setData传输JSON

$() 函数未按预期工作

vue+html5+原生dom+原生JavaScript实现跨区域拖放

html5怎么实现元素随意拖到,是改变位置,不是把元素拖动到另一个元素里面

高分请教,js的DOMNodeRemoved事件如何在删除节点之后才执行这个事件呢