Chrome Apps,FileSystem API:chooseEntry方法不起作用

时间:2014-06-18 11:17:49

标签: javascript google-chrome google-chrome-app

编辑:发现错误,但无法解决,请参阅下文。

的manifest.json

{
    ...
    "offline_enabled": true,
    "app": {
        "background": {
            "persistent": true,
            "scripts": [
                "/js/background.js"
            ]
        }
    },
    "permissions": [
        "notifications",
        "storage",
        {"fileSystem": ["directory"]}
    ]
}

background.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的清单声明的不同变体,但由于该函数在脚本执行中未定义,因此清单不太可能成为问题。

当我使用official example API的fileSystem扩展程序时,应用程序正常运行,因此Chrome设置也不是问题所在。问题似乎是我的代码,但我迷失了。

编辑:我添加了每个文件的内容

编辑2:发现错误,现在该怎么解决?

我在金丝雀尝试了,并意识到错误是通过chrome.runtime.lastError显示的,而不是普通的控制台。这就是我得到的错误。

  

无效的呼叫页面。无法从后台页面调用此功能。

但这不是在background.js中,这是在index.html中从index.html调用的。

1 个答案:

答案 0 :(得分:2)

我刚刚在Chrome中试过这个,而且您发布的代码似乎没有任何问题。我怀疑你加载javascript的方式有问题,或者可能是它正在运行的上下文(前台页面与后台页面)

例如,如果您的JavaScript代码段实际位于main.js,那么它将在后台页面中运行,其windowdocument元素将不会来自你的主页。

我的测试应用看起来与您的非常相似,只是我从清单中遗漏了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对象,该对象被记录到控制台(前台页面,不是背景页面。右键单击应用程序窗口并选择“Inspect Element”,而不是“Inspect”背景页面“,查看前台控制台。”:

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

会在页面上正确找到元素,并将点击处理程序附加到它。