以chrome扩展名打开(导入)文件

Open (Import) file in a chrome extension

本文关键字:导入 文件 chrome 扩展名      更新时间:2023-09-26

我正试图为我的chrome扩展开发导入功能,但这项任务似乎比预期的要困难。

实际上我的想法是使用

<input type="file" id="myInput">

加载文件,然后在该元素上添加一个更改侦听器:

element.addEventListener('change', function(evt){
    read_single_file(evt,tab);
}

现在我面临几个问题:

  1. 第一个问题是,当打开的对话框打开时,弹出窗口会关闭,这会导致所有相关的对象和代码都被弹出页面破坏。看看其他问题,这是chrome扩展的正常行为,当它失去焦点时,弹出窗口将被破坏
  2. 我找到了另一个解决方案,建议将文件逻辑添加到背景页中,如果弹出窗口失去焦点,它不会被破坏。然后我在后台添加了这个功能:

    file_import = function(element, tab) {
        element.addEventListener('change', function(evt){
            read_single_file(evt,tab);
        }, false);
        element.click();
        console.log("uffa");
    }
    

然后我更新了我的popup.js,调用后台方法:

    get_current_tab(function(tab){
        var BGPage = chrome.extension.getBackgroundPage();
        BGPage.file_import(document.getElementById('myInput'), tab);
    });

通过这种方式,file_import被弹出窗口调用,它将更改侦听器添加到myInput元素中,并打开"文件打开"对话框,但。。。打开文件对话框,弹出窗口消失了,所有相关的东西都消失了,然后。。。同样的问题再次出现。

所以我决定尝试在后台页面中创建一个新的输入文件元素,并从中触发点击事件,但显然这不起作用。

所以,我被困在这里,对如何解决这个问题没有好的想法。或者至少我脑子里有几个,但我不知道它们是否有效,或者它们只是变通方法。

  • 其中之一是将导入功能移到devtools区域(因为它是一个对开发人员有用的扩展,所以这是有意义的),我希望打开文件对话框不会导致我的扩展被破坏
  • 或者另一种可能是将导入文件逻辑移动到一个外部页面中,该页面打开一个新选项卡并从文件中导入值。在这种情况下,由于我只需要访问,除了文件内容是当前的标签URL,也许我不必使用Google Chrome API
  • 第三个想法是将一个html元素注入当前页面,然后通过将监听器直接添加到该元素的扩展来访问它,在这种情况下,如果弹出窗口被破坏,我不认为我的监听器会被破坏(页面将在导入后重新加载,所以我的隐藏输入将只保留操作所需的时间)

综上所述,我的问题是:

  1. 有一种干净的方法可以读取chrome扩展插件内的文件内容,而无需使用外部文件、打开新的选项卡等(如果可能的话,我更喜欢将所有内容都保留在扩展插件内)
  2. 如果否,是否可以用JavaScript文件预填充新选项卡
  3. 我可以为当前页面中的DOM元素添加一个监听器吗

最后,我决定选择第三个选项,这在我看来是最简单、最快实现的选项(从文件中读取内容并更新URL)。

我做了什么:

在我的popup.js中,当用户按下导入按钮时,我调用chrome.tabs.executeScript并读取一个文件,其中包含要注入当前选项卡页面的代码:

else if(e.target.id=="import") {
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    chrome.tabs.executeScript(tabs[0].id, {file: "src/content_script.js"});
  });
}

然后我移动了content_script.js文件中的所有导入逻辑,其中I:

  1. 使用document.createElement创建一个新的输入文件元素
  2. 将此元素附加为html <body>的子元素
  3. 从元素触发点击事件(需要提醒的是,chrome中的.click事件不能在不属于任何DOM对象的对象上触发)
  4. 处理输入文件的更改事件

这是代码:

var fileChooser = document.createElement("input");
fileChooser.type = 'file';
fileChooser.addEventListener('change', function (evt) {
  var f = evt.target.files[0];
  if(f) {
    var reader = new FileReader();
    reader.onload = function(e) {
      var contents = e.target.result;
      /* Handle your document contents here */
      document.location.href = url_array; // My extension's logic
    }
    reader.readAsText(f);
  }
});
document.body.appendChild(fileChooser);
fileChooser.click();

在内容脚本中,我似乎无法访问chrome.tabs对象,所以在我的情况下,我决定使用通常的document.location.href来更改URL。