拖放跨域iframe

时间:2017-10-10 09:17:17

标签: javascript iframe google-chrome-extension drag-and-drop

我正在尝试从父网页拖放到跨域的iframe。 iframe由内容脚本通过chrome扩展加载。但是由于内容脚本加载了跨域iframe,我无法使用HTML5从父页面拖放到iframe。

我经历使用iframe的痛苦的原因是为了避免使用CSS corruption

我想采取的方法是:

有一种方法可以通过window.postMessage()在父级和跨源iframe之间进行通信。所以我想我会尝试模拟iframe中父页面中发生的拖动操作,方法是将父内部的每个拖动相关操作信息发送到子iframe。

我所做的是在iframe中创建一个div,其内容包含父级dragstart中拖动元素的内容。在drag上,使用父级提供的坐标在iframe内连续拖动div

// CONTENT SCRIPT CODE

const setEventListener = name => {
  document.body.addEventListener(name, event => {
    const data = {
      dndType: name,
      clientX: event.clientX,   // clientX for iframe should map from clientX from parent exactly, I think
      clientY: iframeContainer.getBoundingClientRect().top - event.clientY,    // iframeContainer is placed at the bottom
      htmlContent: name === 'dragstart' && event.dataTransfer.getData('text/html')
    }
    iframe.contentWindow.postMessage(data, '*')
  })
}
setEventListener('dragstart')
setEventListener('drag')
setEventListener('dragend')



// IFRAME CODE

let dragger
window.addEventListener('message', function(e) {
  if (!dragger) {
    dragger = document.createElement('div')
    document.body.appendChild(dragger)
  }
  if (e.data.dndType) {
    if (e.data.htmlContent && e.data.htmlContent.length > 0) {
      dragger.innerHTML = e.data.htmlContent
    }
    const newEvent = createEvent(
      e.data.dndType,
      {
        clientX: e.data.clientX,
        clientY: e.data.clientY,
        dataTransfer: new DndSimulatorDataTransfer(),
      }
    )
    newEvent.dataTransfer.setData('text/html', dragger.innerHTML)
    dragger.dispatchEvent(newEvent)
  }
})

const createEvent = (eventName, options) => {
  var event = document.createEvent("CustomEvent");
  event.initCustomEvent(eventName, true, true, null);

  event.view = window;
  // event.detail = 0;
  event.ctlrKey = false;
  event.altKey = false;
  event.shiftKey = false;
  event.metaKey = false;
  event.button = 0;
  event.relatedTarget = null;

  /* if the clientX and clientY options are specified,
  also calculated the desired screenX and screenY values */
  if(options.clientX && options.clientY) {
      event.screenX = window.screenX + options.clientX;
      event.screenY = window.screenY + options.clientY;
 }

 /* copy the rest of the options into
  the event object */
  for (var prop in options) {
      event[prop] = options[prop];
  }

  return event;
}

var DndSimulatorDataTransfer = function() {
    this.data = {};
};
DndSimulatorDataTransfer.prototype.setData = function(format, data) {
    this.data[format] = data;
    this.items.push(data);
    this.types.push(format); 
};
// Remaining DndSimulatorDataTransfer prototype methods
// Taken from https://github.com/Photonios/JS-DragAndDrop-Simulator/blob/master/dndsim.js

我在此代码中尝试了不同的变体,但iframe方面仍然没有活动。我甚至不确定这种方法是否有用。

这在技术上是否可行?或者我还有其他方法可以尝试。我认为this guy正在谈论同样的方法。

需要帮助!

0 个答案:

没有答案