【问题标题】:Can't return selected text on Chrome Extension无法在 Chrome 扩展程序上返回选定的文本
【发布时间】:2013-12-16 09:16:05
【问题描述】:

我想在按下快捷键时返回选定的文本。

这是我的代码:

chrome.commands.onCommand.addListener(function(command) {
    console.log(window.getSelection().toString());
});

即使我当前选择了文本,它也不会返回任何内容。 如果我删除 toString,这是输出:

anchorNode: null
anchorOffset: 0
baseNode: null
baseOffset: 0
extentNode: null
extentOffset: 0
focusNode: null
focusOffset: 0
isCollapsed: true
rangeCount: 0
type: "None"

知道如何实际返回我的选择吗?

【问题讨论】:

标签: javascript google-chrome google-chrome-extension selection


【解决方案1】:

侦听器已添加到您的背景页面中,因此window.getSelection() 指的是在您(自动生成的)背景页面中选择的文本,而不是在活动选项卡中。 为了从活动选项卡中检索选定的文本,您需要注入一些代码来为您完成并报告结果。

例如:

background.js:

/* The function that finds and returns the selected text */
var funcToInject = function() {
    var selection = window.getSelection();
    return (selection.rangeCount > 0) ? selection.toString() : '';
};

/* This line converts the above function to string
 * (and makes sure it will be called instantly) */
var jsCodeStr = ';(' + funcToInject + ')();';

chrome.commands.onCommand.addListener(function(cmd) {
    if (cmd === 'selectedText') {
        /* Inject the code into all frames of the active tab */
        chrome.tabs.executeScript({
            code: jsCodeStr,
            allFrames: true   //  <-- inject into all frames, as the selection 
                              //      might be in an iframe, not the main page
        }, function(selectedTextPerFrame) {
            if (chrome.runtime.lastError) {
                /* Report any error */
                alert('ERROR:\n' + chrome.runtime.lastError.message);
            } else if ((selectedTextPerFrame.length > 0)
                    && (typeof(selectedTextPerFrame[0]) === 'string')) {
                /* The results are as expected */
                alert('Selected text: ' + selectedTextPerFrame[0]);
            }
        });
    }
});

manifest.json:

{
    "manifest_version": 2,

    "name":    "Test Extension",
    "version": "0.0",

    "background": {
        "persistent": false,
        "scripts": ["background.js"]
    },

    "permissions": ["<all_urls>"],

    "commands": {
        "selectedText": {
            "description": "Retrieve the selected text in the active tab"
        }
    }
}

还有一点需要注意:

根据 this answer(以及我自己使用 Chrome v31 的经验),关于声明键盘快捷键(又名命令)的官方文档是错误地罢工> 声明您可以以编程方式设置组合键。
事实(如上述答案中的“被盗”)是:

在 Chrome 29(及更高版本)上,您必须导航到 chrome://extensions/ 并向下滚动到页面底部。右侧有一个按钮Keyboard shortcuts

弹出模式对话框,其中包含在清单文件中注册了某些命令的所有扩展。但是快捷方式本身是Not set,所以用户必须手动设置它们。

(强调我的)

更新:

真相是这样的:

  • 如果suggested_key已在用户平台上用作keyboard shortcut,则绑定按预期工作。

  • 如果suggested_key 已绑定到不同的命令,则未设置绑定。用户必须导航到chrome://extensions/ 并单击页面底部的Keyboard shortcuts 按钮。在弹出的对话框中,用户必须手动为注册的命令分配快捷方式。

  • 测试时,修改manifest中的suggested_key后,需要卸载并重新安装扩展才能使修改生效。简单地重新加载或禁用并重新启用扩展是行不通的。 (感谢rsanchez,感谢您的收获。)

【讨论】:

  • @GastonFlanchard:你注意到我更新的答案了吗?最后一部分有点不准确,所以我修改了。顺便说一句,如果这个答案帮助您解决了您的问题,请mark it as "accepted",以便将来遇到类似问题的用户能够轻松发现它。也欢迎投票:)
  • 您好,感谢您的回复!我还没有尝试您的建议,但我会在接下来的几天内尝试:) 然后我会将其标记为已接受。再次感谢你:)
  • 嗨!我不确定理解这一行的目的:“var jsCodeStr = ';(' + funcToInject + ')();';”以及它是如何工作的。如果您有宝贵的时间向我解释一下,那就太好了;)
  • 我建议您将jsCodeStr 打印到控制台并亲自查看该行的结果(这比我能给出的任何解释都要好)。基本上,它接受一个函数(即funcToInject)并将其转换为字符串,以将其作为chrome.tabs.executeScript()code 属性的值传递。此外,它将函数封装在(...) 中,最后立即调用它(参见结尾的())。
  • 这被称为 Immediately-invoked function expression 并且等同于function funcName() {...} funcName()(但有一些好处:更容易区分,不会“污染”全局window对象等)。
猜你喜欢
  • 2021-10-03
  • 2013-09-03
  • 2023-03-12
  • 2015-06-24
  • 2013-10-10
  • 2015-03-09
  • 1970-01-01
  • 2017-04-06
  • 1970-01-01
相关资源
最近更新 更多