我正在尝试从父网页拖放到跨域的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正在谈论同样的方法。
需要帮助!