首页 > 解决方案 > 允许在 Chrome 中的 dragenter 事件处理程序上访问拖动的项目数据

问题描述

我正在为 Angular 6 应用程序开发一个网格组件,其中每个单元格都包含一个对象列表,用户可以将这些对象拖放到网格中的其他单元格中。每个对象都有一个类型,它们只能根据该类型放入某些列的单元格中。例如,“PC”类型的对象只能放在第 3 列和第 4 列的单元格中,“用户”只能放在第 2 列中,依此类推。为了让用户清楚,当一个对象可以放在单元格中时,我想用绿色突出显示,如果不允许,我想用红色突出显示。

我正在使用标准的 HTML5 拖放,所以想法是在dragstart事件上设置对象类型并在处理程序上使用它dragenter来执行逻辑并在放置容器上显示允许/拒绝状态·这是代码的一部分:

onDragStart(item: any, e: DragEvent) {
    e.stopPropagation();

    e.dataTransfer.setData("objType", item.objType);

    e.dataTransfer.effectAllowed = "copyMove";
}


listDragEnter(e: DragEvent) {
    let dragItemType: string;    

    dragItemType = e.dataTransfer.getData("objType");

    if(this.isObjectAllowed(dragItemType)) {
        // THE DRAGGED OBJECT IS ALLOWED IN THIS CELL
    }
    else {
        // NOT ALLOWED
    }
}

这在 Firefox 上运行良好,但在 Chrome(也不是 Opera 或 Safari)上运行良好。我读过,出于安全原因,Chrome 只允许在dragstart处理程序上设置事件数据并在其中读取它drop。我知道可能存在可以读取数据的恶意 iframe,但这种措施使我们无法在此类情况下使用 HTML5 DnD。

有什么方法可以告诉 Chrome(和其他受影响的浏览器)绕过此安全检查并允许从dragenter事件中读取事件数据(如果它们没有在 iframe 上捕获)?

如果没有,关于如何做到这一点的任何想法?谢谢!

标签: javascriptangularhtml

解决方案


这里没有解决方法,Chrome 不允许从dragstartanddrop处理程序访问 dataTransfer 对象。所以,我所做的是添加一个全局服务来将拖动的对象存储在dragstart事件上并在处理程序上读取它drop

就像是:

itemDragStart(item: Item, e: DragEvent) {
  [...]

  this.globalItemService.setDragItem(item);

  [...]
}

itemDragDrop(e: DragEvent) {
  let item: Item;
  [...]

  item = this.globalItemService.getDragItem();

  [...]
}

推荐阅读