【问题标题】:Chrome Apps, FileSystem API: chooseEntry method isn't workingChrome 应用程序,文件系统 API:chooseEntry 方法不起作用
【发布时间】:2014-06-18 11:17:48
【问题描述】:

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

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

当我使用fileSystem API 的official example 扩展时,应用程序可以正常工作,因此 chrome 设置也不是问题。问题似乎是我的代码,但我在这里迷路了。

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

编辑2:发现错误,现在如何解决?

我在 canary 中尝试过,发现错误是通过 chrome.runtime.lastError 而不是普通控制台显示的。这就是我得到的错误。

调用页面无效。无法从后台页面调用此函数。

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

【问题讨论】:

  • 回滚编辑:fileSystem API 不可用于扩展
  • 酷,不知道。
  • 你在使用 jQuery 吗?
  • 不,纯 ol' javascript。无论如何,我将如何在 jquery 中调用 chrome API?编辑:哦,$ 函数是我自己的,而不是 jquery。只是getelementbyidqueryselectorall 的简写。
  • Chrome 应用程序在 jQuery 上运行良好;它只是 JavaScript。你会像其他任何东西一样称呼他们。但是,当您的代码包含 $('input') 时,看起来您正在使用 jQuery 来查找页面中的元素。

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


【解决方案1】:

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

例如,如果您的 JavaScript 代码 sn-p 实际上在 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 对象,该对象会记录到控制台(前台页面,而不是后台页面。在应用程序窗口中右键单击并选择“检查元素”,而不是“检查Background Page”,查看前台控制台。):

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

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

【讨论】:

  • 这正是我正在做的事情。我从 background.js 打开一个 index.html 选项卡,其中 index.js 具有 chooseEntry 调用。我愿意相信问题出在我加载脚本的方式上,但该函数在上下文中可用并成功执行。这意味着上下文是正确的。而且我没有使用 jquery,那个 $ 函数是我自己的 getelementbyid 的简写。一个区别是我使用window.open() 而不是chrome.app.window.create 因为我希望它是一个选项卡而不是一个新窗口。我现在将尝试使用chrome.app.window
  • PS 我刚刚添加了每个文件的内容,就像您在答案中所做的那样。刚刚在金丝雀频道尝试过,结果相同。
  • 啊等等,我在 canary 中找到了一些东西,Unchecked runtime.lastError while running fileSystem.chooseEntry: Invalid calling page. This function can't be called from a background page. 但它不是背景页面,它是 index.html。知道发生了什么吗?
  • 听起来您仍在后台页面中加载处理程序,例如在清单中的 main.js 中。检查后台页面,在“源”选项卡中应该可以看到正在使用的 js 文件。
  • 我尝试从应用程序和清单中完全删除 main.js 并重新加载扩展,以便 index.js 是 index.html 加载的唯一文件。还是同样的错误。看看,i.imgur.com/i4Gu7Ar.png 我现在没有使用任何 $ 函数。 index.js 之外没有任何内容。并且它没有加载到清单中,只有 background.js 是。
猜你喜欢
  • 2015-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多