当用户触发某个keydown
事件时,我正在尝试制作一个chrome扩展,以替换在当前<textarea>
中键入的最后一个单词。所以我试过了,但并没有真正奏效。
以下是我的扩展名文件:
我的分机的manifest.json
:
{
"name": "Test",
"description": "test",
"version": "0.0.1",
"permissions": [
"activeTab"
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_title": "replace test"
},
"manifest_version": 2
}
其background.js
:
chrome.tabs.executeScript(null, {file: "content_script.js"});
及其content_script.js
:
document.onkeydown = replacePrevWord;
// Azerty: Ctrl + ²
// Qwerty: Ctrl + '
function KeyPress(e) {
var evtobj = window.event? event : e
if (evtobj.keyCode == 222 && evtobj.ctrlKey)
return true;
}
function getCaretPosition(ctrl) {
var CaretPos = 0; // IE Support
if (document.selection) {
ctrl.focus();
var Sel = document.selection.createRange();
Sel.moveStart('character', -ctrl.value.length);
CaretPos = Sel.text.length;
}
// Firefox support
else if (ctrl.selectionStart || ctrl.selectionStart == '0')
CaretPos = ctrl.selectionStart;
return (CaretPos);
}
function returnWord(text, caretPos) {
var index = text.indexOf(caretPos);
var preText = text.substring(0, caretPos);
if (preText.indexOf(" ") > 0) {
var words = preText.split(" ");
return words[words.length - 1]; //return last word
}
else {
return preText;
}
}
function replacePrevWord() {
if(KeyPress()){
var text = document.activeElement;
var caretPos = getCaretPosition(text)
var word = returnWord(text.value, caretPos);
if (word != null) {
text.value = text.value.replace(word,"replaced");
}
}
}
这在JSFiddle上运行良好(http://jsfiddle.net/cyo646cr/3/),但我不知道如何在Chrome扩展中做到这一点。
有什么想法吗?
谢谢。
注意:自2021年1月起,使用具有chrome.scripting.executeScript()
和scripting
权限的Manifest V3,并将<all_urls>
移动到host_permissions
,而不是使用具有tabs
权限的不推荐使用的chrome.tabs.executeScript()
。
问题
您没有正确地注入脚本。这很容易说,因为调用这个简单的线路
chrome.tabs.executeScript(null, {file: "content_script.js"});
在background.js
中,将导致在当前选项卡中仅注入一次脚本(因为未指定tabId)。因此,在您打开的第一个选项卡中,您的脚本将只在Google Chrome的每个会话中运行一次。
查看chrome.tabs.executeScript
的文档。
解决方案
要解决这个问题,你有两个选择:
- 在
manifest.json
中声明"content_scripts"
字段,这样它将被注入到任何与模式匹配的页面中 - 使用
chrome.tabs.onUpdated.addListener
方法添加一个监听器,并在选项卡上注入脚本
选项1
像这样声明manifest.json
中的"content_scripts"
字段:
...
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content_script.js"],
"run_at": "document_idle",
"all_frames": true
}
],
...
现在,您的内容脚本将被注入到每个页面(因为"<all_urls>"
将匹配所有页面)和页面的所有框架中。您可以在此处找到有关"content_scripts"
的有用信息。
选项2
请求chrome.tabs
API的权限以及manifest.json
:中所需的URL
...
"permissions": [
"activeTab",
"tabs",
"<all_urls>"
]
...
在background.js
中,向chrome.tabs.onUpdated
添加一个监听器,它将在每次选项卡更新(即url更新)时启动,并使用chrome.tabs.executeScript
注入脚本,如下所示:
chrome.tabs.onUpdated.addListener(function(tabID, info, tab) {
chrome.tabs.executeScript(tabID, {file: "content_script.js"});
});
请参见chrome.tabs.onUpdated
的文档。