【发布时间】:2019-12-23 05:17:10
【问题描述】:
我正在尝试在浏览器扩展的内容脚本中模拟放置事件(使用拖放 API)。本质上,我想模拟用户以编程方式放置图像。到目前为止我有这个:
const dataTransfer = new DataTransfer();
dataTransfer.items.add(file); // File object representing image being dropped
const event = new DragEvent('drop', { dataTransfer });
document.body.dispatchEvent(event);
当所有模拟都在浏览器中本地进行时,这在 Chrome 和 Firefox 上都非常有效。 This JSFiddle 在这两种浏览器中都非常有效——如果您上传文件,则会模拟下降,并且图像会显示在预览中。
问题是当我尝试使用浏览器扩展完成完全相同的事情时,我在 Firefox(但不是 Chrome)中遇到了问题。我整理了一个demo extension,它完成了与 JSFiddle 相同的事情,但带有一个内容脚本。在 Chrome 上,该扩展程序会注入文件输入并完美模拟下降(图像显示在#preview):
您可以看到(在手绘圆圈中)dataTransfer.files 的长度为 1——拖放的图像文件在列表中。但是当我在 Firefox 上使用完全相同的扩展时:
图片已上传(请参阅输入),但未删除并显示在预览中。从控制台可以看到dataTransfer.files在Firefox中是空的,尽管dataTransfer.items里面有文件!
为什么这里有差异?我检查了 Mozilla 的兼容性检查器,它说我的扩展已准备好跨平台。 By then HTML5 spec files 应该与 items 同步,并且没有条件 AFAICT 保证 Firefox 上的空列表。这可能是一个错误吗?
【问题讨论】:
-
这可能是一个错误,但知道 Firefox,我猜这是他们仍然提供 cloneInto and stuff like wrappedJSObject 的上下文的历史分离。
-
@wOxxOm 感谢您的链接。我在 WrappedJSObject 上做了一些阅读,我尝试做
new window.DataTransfer和new window.DragEvent却没有运气。不过,Xray 会与特定的 File 实例混淆,这似乎很奇怪。 -
window仍然指的是内容脚本的窗口,但我认为这里需要window.wrappedJSObject或明确使用 cloneInto。至于“奇怪”,因为内容脚本在一个孤立的世界中运行,我想说它们不共享复杂类型是可以理解的,因为可能很难改变历史上实现分离的方式。 -
@wOxxOm 你完全正确!该文件最终出现在
DataTransfer对象中,现在可以分派它了!非常感谢你——如果你能发布一个很棒的答案。
标签: javascript google-chrome firefox google-chrome-extension firefox-addon