在Chrome扩展中打开(导入)文件 [英] Open (Import) file in a chrome extension

查看:570
本文介绍了在Chrome扩展中打开(导入)文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图为我的Chrome扩展开发导入功能,但这个任务似乎比预期的更困难。

实际上我的想法是使用

 < input type =fileid =myInput> 

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

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

现在我遇到了几个问题:


  1. 第一个问题是弹出窗口在打开对话框打开时会关闭,并且会导致所有相关的对象和代码被弹出页面销毁。并且查看其他问题,这是正常行为当它失去焦点时,弹出窗口将被销毁。

  2. 我找到了另一个解决方案,建议将文件逻辑添加到背景页面中,这不会是如果弹出窗口丢失了焦点,就会被销毁。然后我在后台添加了这个函数:

      file_import = function(element,tab){

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


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

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

通过这种方式,file_import被popup调用,它将更改侦听器添加到myInput元素,并且打开文件打开对话框,但是...打开文件对话框弹出消失了,以及与之相关的所有内容,然后...再次出现同样的问题。



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



所以,我被困在这里,没有好的想法来解决这个问题。或者至少我在我的脑海里很少,但我不知道他们是否工作,或者他们只是解决方法。


  • 其中之一是将导入功能移到devtools区域(因为它是对开发人员有用的扩展)我希望打开的文件对话框不会导致我的扩展被破坏。 另一个可能是将导入文件逻辑移入外部页面,该页面打开一个新选项卡并从文件中导入值。在这种情况下,由于我只需要访问,除了文件内容是当前标签网址,也许我不必使用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 file,其中I:


  1. 使用文档创建新的输入文件元素.createElement

  2. 将此元素附加为html < body> 的子元素。

  3. 从元素中触发单击事件(重要的是提醒您在chrome中的 .click 事件不能在不属于任何DOM对象)。

  4. 处理输入文件的更改事件。

这里是代码:

  var fileChooser = document.createElement(input); 
fileChooser.type ='文件';

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;
/ *处理文档内容* /
document.location.href = url_array; //我的扩展逻辑
}
reader.readAsText(f);
}
});

document.body.appendChild(fileChooser);
fileChooser.click();

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


I'm trying to develop import feature for my chrome extension, but this task seems more difficult then expected.

Actually my idea is to use an

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

TO load the file and then add a change listener on that element:

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

Now there are several problem that i'm facing:

  1. The first problem is that the popup is closed when the open dialog opens, and it causes all related object and code to be destroyed with the popup page. And looking at other question, this is the normal behaviour of a chrome extension, when it lost focus the popup will be destroyed.
  2. I found another solution, that suggests to add the file logic into the background page, that will not be destroyed if the popup lost focus. Then i added this function in background:

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

And then i updated my popup.js to call the background method:

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

And in that way the file_import is called by popup, it adds the change listener to myInput element, and opens up the File Open dialog but... opening the file dialog the popup is gone, and everything related to it, then... same problem again.

So i decided to try to create a new input file element in background page, and trigger click event from it, but obviously it doesn't work.

So, I'm stuck here, with no good ideas on how to solve that problem. Or at least i have few in my mind, but i don't know if they work, or they are just workaround.

  • One of them is to move the import feature into the devtools area (since it is an extension useful for developer it makes sense), where I hope that the open file dialog, doesn't cause to my extension to be destroyed.
  • Or another maybe could be to move the import file logic into an external page that opens a new tab and import the values from the files. In that case, since what I need only to access, except the file content is the current tab URL, maybe I don't have to use Google Chrome API.
  • The third idea is to inject an html element into the current page, and then access it from the extension adding the listener directly to that element, and in that case i don't think that my listener is destroyed if the popup is destroyed (the page will be reloaded just after the import, so my hidden input will stay just for the time needed for the operation).

To sum up my questions are:

  1. There is a clean way to read file content inside a chrome extension, without the need to use external files, open new tabs, etc (if possible i prefer to keep everything inside the extension)?
  2. If no is possible to prepopulate a new tab with a JavaScript file?
  3. Can i add a listener to DOM elements inside the current page?

解决方案

Finally I decided for the third option, which was in my opinion, and for my purposes (read content from a file and update a URL) the easiest and fastest to implement.

Here what I did:

In my popup.js, when the user presses the import button, I call chrome.tabs.executeScript and read a file with the code to be injected into the current tab page:

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"});
  });
}

Then I moved all the import logic in the content_script.js file, where I:

  1. Create a new input file element using document.createElement.
  2. Append this element as child of html <body>.
  3. Trigger click event from the element (it is important to remind that the .click event in chrome cannot be triggered on object that are not part of any DOM object).
  4. Handle change event for the input file.

Here is the code:

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();

It seems that in a content script I cannot access the chrome.tabs object, so in my case I just decided to use the usual document.location.href to change the URL.

这篇关于在Chrome扩展中打开(导入)文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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