我正试图为我的chrome扩展开发导入功能,但这项任务似乎比预期的要困难。
实际上我的想法是使用
<input type="file" id="myInput">
加载文件,然后在该元素上添加一个更改侦听器:
element.addEventListener('change', function(evt){
read_single_file(evt,tab);
}
现在我面临几个问题:
- 第一个问题是,当打开的对话框打开时,弹出窗口会关闭,这会导致所有相关的对象和代码都被弹出页面破坏。看看其他问题,这是chrome扩展的正常行为,当它失去焦点时,弹出窗口将被破坏
我找到了另一个解决方案,建议将文件逻辑添加到背景页中,如果弹出窗口失去焦点,它不会被破坏。然后我在后台添加了这个功能:
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元素注入当前页面,然后通过将监听器直接添加到该元素的扩展来访问它,在这种情况下,如果弹出窗口被破坏,我不认为我的监听器会被破坏(页面将在导入后重新加载,所以我的隐藏输入将只保留操作所需的时间)
综上所述,我的问题是:
- 有一种干净的方法可以读取chrome扩展插件内的文件内容,而无需使用外部文件、打开新的选项卡等(如果可能的话,我更喜欢将所有内容都保留在扩展插件内)
- 如果否,是否可以用JavaScript文件预填充新选项卡
- 我可以为当前页面中的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:
- 使用
document.createElement
创建一个新的输入文件元素 - 将此元素附加为html
<body>
的子元素 - 从元素触发点击事件(需要提醒的是,chrome中的
.click
事件不能在不属于任何DOM对象的对象上触发) - 处理输入文件的更改事件
这是代码:
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。