在提供文件数据时触发'drop'事件 [英] Trigger 'drop' event while providing the file data

查看:88
本文介绍了在提供文件数据时触发'drop'事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题

在提供文件时,我怎么能触发 drop 字段事件,我在加载时无法访问

How could I, while providing the file, trigger a drop event of a field, on which I do not have access at loading.

详细信息

有一个字段,其上附有 drop 监听器,该监听器在删除时处理图像。我希望能够通过粘贴图像来使用此过程。我知道如何从粘贴中获取文件,但我不知道如何发送包含此文件的 drop 事件。

There is a page with a field on which is attached a drop listener that process an image when dropped. I would like to be able to use this process by pasting an image. I know how to get the file from a paste, but I do not know how to dispatch a drop event that would contains this very file.

障碍是:


  • 代码被混淆,我无法通过名称访问与监听器链接的功能。

  • 在附加到元素后,无法获取 drop 侦听器。 似乎有一些方法可以在控制台中执行,但不是从脚本中执行。

  • 我不控制页面呈现;即我无法拦截事件监听器的添加。

  • Vanilla Javascript&只能在Chrome(扩展程序)中使用。

  • 此页面内置于vanilla中;即没有jQuery或任何东西。

  • The code is obfuscated, I cannot access the function linked with the listener by name.
  • There is no way to get the drop listener after it being attached to an element. It seems there is some way to do it in the console, but not from a script.
  • I do not control the page rendering; i.e. I cannot intercept the event listener addition.
  • Vanilla Javascript & could only work in Chrome (extension).
  • This page is built in vanilla; i.e. no jQuery or anything.

有没有人知道如何解决这个问题?

Does anyone have an idea on how to tackle this task?

我正在研究 DragEvent 但是虽然这个接口有一个构造函数,但是不可能从脚本创建一个有用的DataTransfer对象,因为DataTransfer对象有一个处理和安全模型,在浏览过程中由浏览器协调 - & - -drop。

我看到了一种可能的方法 https://stackoverflow.com/a/39066443/1004274 但我想用其数据模仿真实的 drop事件,即传递我通过获得的文件clipboardData.items [0] .getAsFile(); 而不仅仅是文本。

I saw a possible approach https://stackoverflow.com/a/39066443/1004274 but I want to mimic a real drop event with its data, i.e. pass a file I got via clipboardData.items[0].getAsFile(); instead of just text.

推荐答案

你可以假冒 drop 事件,并伪造了那里的所有内容。您遇到的问题是触发默认事件,例如通过删除选项卡来打开文件。原因并非如此,因为 dataTransfer 对象受到保护,但事件不受信任。通过拥有受信任的事件和受保护的dataTransfer,您可以确保不会将数据传递给受信任的事件,并且不会使用不需要的数据触发默认事件。

You can fake the drop event, and fake pretty much everything that's in there. What you'll have problem doing is triggering a default event, such as opening a file in a tab by dropping it. The reason isn't so much because of the dataTransfer object being protected, but the event not being trusted. By having trusted event and protected dataTransfer, you can be sure you won't pass data to a trusted event, and that you won't trigger default event with unwanted data.

但是根据drop函数如何访问被删除的文件,你可能会使用假的 drop 事件来欺骗它。假的 dataTransfer 对象。看看这个小提琴,了解它如何运作:

But depending on how the drop function is accessing the file that is dropped, you might be able to trick it with a fake drop event and a fake dataTransfer object. See this fiddle for a general idea of how it may work:

var a = document.getElementById('link');
var dropZone1 = document.getElementById('dropZone1');
var dropZone2 = document.getElementById('dropZone2');
var fakeDropBtn = document.getElementById('fakeDropBtn');

dropZone1.addEventListener('dragover', function(e) {
  e.preventDefault();
});

dropZone2.addEventListener('dragover', function(e) {
  e.preventDefault();
});

dropZone1.addEventListener('drop', function(e) {
  // This first drop zone is simply to get access to a file.
  // In your case the file would come from the clipboard
  // but you need to work with an extension to have access
  // to paste data, so here I use a drop event
  e.preventDefault();
  fakeDropBtn.classList.remove('disabled');
  dropZone2.classList.remove('disabled');
  var fileToDrop = e.dataTransfer.files[0];

  // You create a drop event
  var fakeDropEvent = new DragEvent('drop');
  // You override dataTransfer with whichever property
  // and method the drop function needs
  Object.defineProperty(fakeDropEvent, 'dataTransfer', {
    value: new FakeDataTransfer(fileToDrop)
  });

  fakeDropBtn.addEventListener('click', function(e) {
    e.preventDefault();

    // the fake event will be called on the button click
    dropZone2.dispatchEvent(fakeDropEvent);
  });
});



dropZone2.addEventListener('drop', function(e) {
    e.preventDefault();
  // this is the fake event being called. In this case for 
  // example, the function gets access to dataTransfer files.
  // You'll see the result will be the same with a real
  // drop event or with a fake drop event. The only thing
  // that matters is to override the specific property this function
  // is using.
  var url = window.URL.createObjectURL(e.dataTransfer.files[0]);
  a.href = url;
  a.click();
  window.URL.revokeObjectURL(url); 
});

function FakeDataTransfer(file) {
  this.dropEffect = 'all';
  this.effectAllowed = 'all';
  this.items = [];
  this.types = ['Files'];
  this.getData = function() {

    return file;
  };
  this.files = [file];
};

https://jsfiddle.net/5m2u0tux/6/

这篇关于在提供文件数据时触发'drop'事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆