编辑:发现错误,但无法解决,见下文。
manifest.json
{
...
"offline_enabled": true,
"app": {
"background": {
"persistent": true,
"scripts": [
"/js/background.js"
]
}
},
"permissions": [
"notifications",
"storage",
{"fileSystem": ["directory"]}
]
}
背景.js
chrome.app.runtime.onLaunched.addListener(function() {
window.open('/index.html');
});
index.html
<!DOCTYPE html>
<html>
<head>
<title>Achshar Player</title>
<script src="/js/index.js"></script>
</head>
<body>
<input id="input" type="button">
</body>
</html>
index.js
window.addEventListener('load', function() {
document.getElementById('input').addEventListener('click', function() {
chrome.fileSystem.chooseEntry({type: 'openFile'}, function(readOnlyEntry) {
console.log(readOnlyEntry);
});
});
});
方法被调用,回调也被调用,但是文件选择对话始终没有出现,并且执行回调时 readOnlyEntry
未定义。开发工具上没有错误,我在 35.0.1916.153 m。
我尝试了 fileSystem
的 list 声明的不同变体,但由于该函数在脚本执行中并未未定义,因此 list 不太可能是问题所在。
当我使用official example时fileSystem 的扩展API 应用程序可以正常工作,因此 chrome 设置也不是问题。问题似乎是我的代码,但我在这里迷失了。
编辑:我添加了每个文件的内容
编辑2:发现错误,现在如何解决?
我在金丝雀中尝试过,并意识到错误是通过 chrome.runtime.lastError 显示的,而不是普通的控制台。这就是我得到的错误。
Invalid calling page. This function can't be called from a background page.
但这不在background.js中,而是在index.js中,它是从index.html调用的。
最佳答案
我刚刚在 Chrome 中尝试过此操作,您发布的代码似乎没有任何问题。我怀疑您加载 javascript 的方式有问题,或者可能是它运行的上下文(前台页面与后台页面)有问题
例如,如果您的 JavaScript 代码片段实际上位于 main.js
中,那么它将在后台页面及其 window
和 document< 中运行
元素不会是主页中的元素。
我的测试应用程序看起来与您的非常相似,只是我从 list 中省略了 main.js
文件,并且构建了一个小的 index.html
文件,它会加载一个 foreground.js
脚本。这是完整的应用程序:
manifest.json
{
"manifest_version": 2,
"name": "Stack overflow question test app",
"version": "1",
"offline_enabled": true,
"app": {
"background": {
"persistent": true,
"scripts": [
"/js/background.js"
]
}
},
"permissions": [
"notifications",
"storage",
{"fileSystem": ["directory"]}
]
}
js/background.js
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create("index.html");
});
index.html
<!DOCTYPE html>
<html>
<head>
<title>TEST</title>
<script src="js/foreground.js"></script>
</head>
<body>
<input id="input" />
</body>
</html>
js/foreground.js
window.addEventListener('load', function() {
document.getElementById('input').addEventListener('click', function() {
chrome.fileSystem.chooseEntry({type: 'openFile'}, function(readOnlyEntry) {
console.log(readOnlyEntry);
});
});
});
当我运行它时,我可以单击输入元素,然后我会看到一个文件选择器。选择一个条目会返回一个 FileEntry 对象,该对象会记录到控制台(前台页面,而不是后台页面)。在应用程序窗口中右键单击并选择“检查元素”,而不是“检查后台页面”,查看前台控制台。):
FileEntry {filesystem: DOMFileSystem, fullPath: "/TestFile.rtf", name: "TestFile.rtf", isDirectory: false, isFile: true…} foreground.js:4
注意:
从您的原始代码来看,您似乎正在使用像 jQuery 这样的框架来搜索页面中的 DOM 元素。 Chrome 应用程序与 jQuery 配合得很好,但您必须注意何时使用原始 DOM Node 对象以及何时使用包装的 jQuery 对象。
具体来说,该行
$('input').addEventListener('click', function() {
会给你带来问题。
替换为
document.querySelector('input').addEventListener('click'), function() {
将正确找到页面上的元素,并将点击处理程序附加到它。
关于javascript - Chrome 应用程序、文件系统 API : chooseEntry method isn't working,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24284144/